내 자신의 질문에 대한 답변을 찾을. 나는 sqlalchemy core의 관점에서 아래를 대표하고 있습니다. 요즘 사용하고있는 것입니다.
같이
파이썬 코드가 보인다 :
from sqlalchemy import Table, Column, String, Integer, MetaData, \
select, func, ForeignKey, text
import sys
from functools import reduce
from sqlalchemy import create_engine
engine = create_engine('sqlite:///:memory:', echo=False)
metadata = MetaData()
linked_list = Table('linked_list', metadata,
Column('id', Integer, primary_key = True),
Column('at', Integer, nullable=False),
Column('val', Integer, nullable=False),
Column('next', Integer, ForeignKey('linked_list.at'))
)
refs = Table('refs', metadata,
Column('id', Integer, primary_key = True),
Column('ref', Integer, ForeignKey('linked_list.at')),
)
placeholder = Table('placeholder', metadata,
Column('id', Integer, primary_key = True),
Column('ref', Integer, ForeignKey('linked_list.at')),
Column('val', Integer, nullable=False),
)
metadata.create_all(engine)
conn = engine.connect()
refs_al = refs.alias()
linked_list_m = select([
linked_list.c.at,
linked_list.c.val,
linked_list.c.next]).\
where(linked_list.c.at==refs_al.c.ref).\
cte(recursive=True)
llm_alias = linked_list_m.alias()
ll_alias = linked_list.alias()
linked_list_m = linked_list_m.union_all(
select([
llm_alias.c.at,
ll_alias.c.val * llm_alias.c.val,
ll_alias.c.next
]).
where(ll_alias.c.at==llm_alias.c.next)
)
llm_alias_2 = linked_list_m.alias()
sub_statement = select([
llm_alias_2.c.at,
llm_alias_2.c.val]).\
order_by(llm_alias_2.c.val.desc()).\
limit(1)
def gen_statement(v) :
return select([refs_al.c.ref, func.max(llm_alias_2.c.val)]).\
select_from(
refs_al.\
join(llm_alias_2, onclause=refs_al.c.ref == llm_alias_2.c.at)).\
group_by(refs_al.c.ref).where(llm_alias_2.c.val > v)
LISTS = [[2,4,4,11],[3,4,5,6]]
idx = 0
for LIST in LISTS :
start = idx
for x in range(len(LIST)) :
ELT = LIST[x]
conn.execute(linked_list.insert().\
values(at=idx, val = ELT, next=idx+1 if x != len(LIST) - 1 else None))
idx += 1
conn.execute(refs.insert().values(ref=start))
def gen_insert(v) :
return placeholder.insert().from_select(['ref', 'val'], gen_statement(v))
print "LISTS:"
for LIST in LISTS :
print " ", LIST
def PRODUCT(L) : return reduce(lambda x,y : x*y, L, 1)
print "PRODUCTS OF LISTS:"
for LIST in LISTS :
print " ", PRODUCT(LIST)
for x in (345,355,365) :
statement_ = gen_insert(x)
print "########"
print "Lists that are greater than:", x
conn.execute(statement_)
allresults = conn.execute(select([placeholder.c.val])).fetchall()
if len(allresults) == 0 :
print " /no results found/"
else :
for res in allresults :
print res
conn.execute(placeholder.delete())
print "########"
결과는 다음과 같습니다
LISTS:
[2, 4, 4, 11]
[3, 4, 5, 6]
PRODUCTS OF LISTS:
352
360
########
Lists that are greater than: 345
(352,)
(360,)
########
Lists that are greater than: 355
(360,)
########
Lists that are greater than: 365
/no results found/
########
그리고 SQL가 발생
비결은 제품을 계산하기 위해 RECURSIVE와를 사용하는 것입니다 파이썬 함수 gen_statement에 의해 만들어진 자리 표시 자 테이블에 삽입됩니다 (더 읽기 쉽도록 들여 쓰기가 변경됨) :
.0 0 맺는
> 365
요청에 대해 오류가 발생합니다 SQLAlchemy의 난 그냥, select 문에 의해 반환 된 행을 반복하는 경우 때문에 호기심
WITH RECURSIVE anon_2(at, val, next) AS
(SELECT linked_list.at AS at, linked_list.val AS val, linked_list.next AS next
FROM linked_list, refs AS refs_1
WHERE linked_list.at = refs_1.ref
UNION ALL
SELECT anon_3.at AS at, linked_list_1.val * anon_3.val AS anon_4, linked_list_1.next AS next
FROM anon_2 AS anon_3, linked_list AS linked_list_1
WHERE linked_list_1.at = anon_3.next)
SELECT refs_1.ref, max(anon_1.val) AS max_1
FROM refs AS refs_1 JOIN anon_2 AS anon_1 ON refs_1.ref = anon_1.at
WHERE anon_1.val > :val_1 GROUP BY refs_1.ref
, 이유는 내가 읽는 다음 placeholder
표를 작성하고있어입니다 행. 이론 상으로는 0 행만 산출됩니다. 그러나 문 결과가 테이블 placeholder
에 삽입 될 때 예상대로 0 행이 삽입됩니다.
그럼 원하는 것은 score1 * score2 * score3> 5 같은 선수를 얻는 것입니까? –
그래, 점수가 각 운동 선수마다 같지 않으므로 알고리즘은 점수가 무엇이든간에 곱해야합니다. – mikesol