2017-08-11 83 views
-1

我有一个sql表格,其中cpcid作为其中的两列。 a, av, b, bv, c, cv是列中的字符串,17, 18在列cid中。python for for循环的sql选择是什么?

for cp in ['a', 'av', 'b', 'bv', 'c', 'cv']: 
    for cid in [17,18]: 
    df= get_dataframes(cp,cid) 
    ccl = str(cid) 
    pickle_name = "ccmp/_" + ccl + "_"+ cp + "_recent.pkl" 

    result_df = pd.Dataframe(df) 

我有2循环的喜欢^在蟒蛇。我需要在SQL中复制它们。我不知道如何使用while循环来做到这一点,因为sql没有直接替代python中的for循环。我正在使用MS SQL Server。我只想复制循环。不是我的python脚本所做的一切,它只是我使用我的for循环的示例。对任何混淆抱歉。

get_dataframes是用cpcid过滤后从一堆其他数据帧中获取数据帧的功能。 for循环的作用是运行cpcid的所有组合的功能,并将它们存储到泡菜中。

我所需要的sql for loop可以给我的cpcid的不同组合。

循环将有一条select语句,给出每个组合的记录(从每个组合的100个记录(即(a,17)(a,18)(av,17)(av,18))开始的2条记录。 。 。

什么我的SQL基本上是应该做的是采取下面的表格,就可以

x y cp cid 
aaa bbb a  22 
aaa bbb a  27 
aaa bbb a  17 
aaa bbb av  17 
aaa bbb b  22 
aaa bbb b  18 
aaa bbb bv  18 
aaa bbb c  22 
aaa bbb cv  18 
aaa bbb c  17 
aaa bbb d  17 
aaa bbb dv  18 
aaa bbb j  17 
aaa bbb a  22 
aaa bbb a  27 
aaa bbb a  17 
aaa bbb av  17 
aaa bbb b  22 
aaa bbb b  18 
aaa bbb bv  18 
aaa bbb c  22 
aaa bbb cv  18 
aaa bbb c  17 
aaa bbb d  17 
aaa bbb dv  18 
aaa bbb j  17 

运行循环,并得到看起来像

x y cp cid 
aaa bbb a  17 
aaa bbb a  17 
aaa bbb av  17 
aaa bbb av  17 
aaa bbb b  18 
aaa bbb b  18 
aaa bbb bv  18 
aaa bbb bv  18 
aaa bbb c  17 
aaa bbb c  17 
aaa bbb cv  18 
aaa bbb cv  18 
+1

什么是循环做替换2 CASE语句?如果你解释说你可能会从不认识Python的人那里得到更好的答案(像我:)) –

+0

@JacobH我编辑了我的问题。我希望有所帮助。如果需要,可以提高清晰度。谢谢:) – beginnerdscientist

+0

所以你需要一个'cp'和一个'cid'的所有可能的组合? 'CROSS JOIN'会为你做到这一点。时间短,否则我会发布答案。 – alroc

回答

1

这取决于循环做什么最终意见。 SQL将数据视为集合,但您可以将其概念化为存在一些循环数据和执行函数的操作。如果你的循环在这里计算你的数据的一些总数,平均值或其他单个值的多个单独值的集合,那么在SQL中这将是一个GROUP BY,以及一些聚合函数,如AVG,SUM等。如果你在python中的循环产生字符串通过串联变量和固定字符串,那么这只是一个简单的select语句和相关的连接命令。如果你的循环在python中......

所以你可以看到,对于有针对性的建议和示例查询,你将不得不向我们展示数据帽块进入你的循环和出来的东西。它不是很明显wha变换应用从开始到结束,他们还需要描述

编辑:根据你所描述的循环来做.. sql处理现有数据块。如果你使用的是一个发明数据的SQL,你真的必须把数据放到select语句中。你的CP和CID可能会因此被这样表示:

Select concat(a.cp,b.cid) from 
(Select 'a' as cp union all select 'av' union all select 'b' ...) a 
Cross join 
(Select '17' as cid union all select '18') b 

他的SQL语句的结果将是CP和CID的每个组合的12行。我将它们传递给了concat命令来证明这一点,但是您可能希望将它们传递给制作泡菜的命令。或酸辣酱。

+0

感谢您的帮助 –

+0

谢谢@caius,我编辑了我的问题了解更多详情。 – beginnerdscientist

1

如果我理解正确你的问题:

Select pickle_name = concat('ccmp/_' , cid , '_' , cp ,'_recent.pkl') 
From (values ('a'),('av'),('b'),('bv'),('c'),('cv')) A(cp) 
Cross Join (Select * from (values (17),(18)) B(cid)) B 

返回

pickle_name 
ccmp/_17_a_recent.pkl 
ccmp/_17_av_recent.pkl 
ccmp/_17_b_recent.pkl 
ccmp/_17_bv_recent.pkl 
ccmp/_17_c_recent.pkl 
ccmp/_17_cv_recent.pkl 
ccmp/_18_a_recent.pkl 
ccmp/_18_av_recent.pkl 
ccmp/_18_b_recent.pkl 
ccmp/_18_bv_recent.pkl 
ccmp/_18_c_recent.pkl 
ccmp/_18_cv_recent.pkl 
+0

谢谢,但我不会看我的泡菜。我只需要在sql中复制python代码。 – beginnerdscientist

+3

你不能,或者你可以,这取决于你的意思是通过复制。约翰在这里写的是正确的,因为你的python代码制作了一个pickle名称列表,他的sql也是如此。他的sql没有使用你可以看到的循环,所以它可能不符合你对'复制'的理解,但这是因为要求sql像python一样工作就像是要求一条鱼来驱动潜艇 –

+0

@beginnerdscientist结果可以是合并到CROSS APPLY或JOIN中。不清楚你想要的结果/最终游戏 –

0

如果我正确你想要什么了解,这可以用一个简单的SELECT来完成。

尝试以下操作:

declare @test table 
(
x char(3), 
y char(3), 
cp varchar(2), 
cid int 
) 

INSERT INTO @test VALUES 
('aaa', 'bbb', 'a',  22), 
('aaa', 'bbb', 'a',  27), 
('aaa', 'bbb', 'a',  17), 
('aaa', 'bbb', 'a',  17), 
('aaa', 'bbb', 'a',  17), 
('aaa', 'bbb', 'a',  17), 
('aaa', 'bbb', 'a',  17), 
('aaa', 'bbb', 'a',  17), 
('aaa', 'bbb', 'a',  17), 
('aaa', 'bbb', 'a',  17), 
('aaa', 'bbb', 'a',  17), 
('aaa', 'bbb', 'a',  17), 
('aaa', 'bbb', 'av',  17), 
('aaa', 'bbb', 'b',  22), 
('aaa', 'bbb', 'b',  18), 
('aaa', 'bbb', 'bv',  18), 
('aaa', 'bbb', 'c',  22), 
('aaa', 'bbb', 'cv',  18), 
('aaa', 'bbb', 'c',  17), 
('aaa', 'bbb', 'd',  17), 
('aaa', 'bbb', 'dv',  18), 
('aaa', 'bbb', 'j',  17), 
('aaa', 'bbb', 'a',  22), 
('aaa', 'bbb', 'a',  27), 
('aaa', 'bbb', 'a',  17), 
('aaa', 'bbb', 'av',  17), 
('aaa', 'bbb', 'b',  22), 
('aaa', 'bbb', 'b',  18), 
('aaa', 'bbb', 'bv',  18), 
('aaa', 'bbb', 'c',  22), 
('aaa', 'bbb', 'cv',  18), 
('aaa', 'bbb', 'c',  17), 
('aaa', 'bbb', 'd',  17), 
('aaa', 'bbb', 'dv',  18), 
('aaa', 'bbb', 'j',  17) 

;WITH cte as 
(SELECT x,y,cp,cid, ROW_NUMBER() OVER (PARTITION BY x,y,cp,cid 
ORDER BY x,y,cp,cid) as row_num 
FROM @test WHERE cp IN('a','av','b','bv','c', 'cv') 
AND cid IN (17,18)) 
SELECT x,y,cp,cid FROM cte WHERE row_num < 3 

这给出了一个结果集:

aaa bbb a 17 
aaa bbb a 17 
aaa bbb av 17 
aaa bbb av 17 
aaa bbb b 18 
aaa bbb b 18 
aaa bbb bv 18 
aaa bbb bv 18 
aaa bbb c 17 
aaa bbb c 17 
aaa bbb cv 18 
aaa bbb cv 18 

编辑

你需要做的性能上的数据检查一点点。显然,你可以通过将< 3更改为< 501来改变我原来的帖子。

可能更快的替代方法是使用计数,然后根据计数生成结果集。具有相同首先声明,并如上插入,但随后走:

declare @test2 table 
(
RecCount int, 
x char(3), 
y char(3), 
cp varchar(2), 
cid int 
) 

INSERT INTO @test2 
SELECT COUNT(*) as RecCount, x, y, cp, cid FROM @test 
WHERE cp IN('a','av','b','bv','c', 'cv') 
AND cid IN (17,18) 
GROUP BY x, y, cp, cid 

declare @cnt int = 1 
declare @insertcnt int 

declare @x char(3) 
declare @y char(3) 
declare @cp varchar(2) 
declare @cid int 
declare @rc int 

declare @results table 
(
x char(3), 
y char(3), 
cp varchar(2), 
cid int 
) 

DECLARE cur CURSOR 
FOR SELECT x, y, cp, cid, CASE WHEN RecCount < 2 THEN RecCount ELSE 2 END FROM @test2 

OPEN cur 

FETCH NEXT FROM cur 
INTO @x, @y, @cp, @cid, @rc 

WHILE @@FETCH_STATUS = 0 
    BEGIN 
     SET @insertcnt = 0 
     WHILE @insertcnt < @rc 
     BEGIN 
      INSERT INTO @results VALUES(@x, @y, @cp, @cid) 
      SET @insertcnt = @insertcnt + 1 
     END 
     SET @cnt = @cnt + 1 
     FETCH NEXT FROM cur 
     INTO @x, @y, @cp, @cid, @rc 
    END 

SELECT * FROM @results 

通常使用游标是缓慢的,但在这里我们知道只会有12条(最多),所以它会很快。这意味着唯一需要检查的是,使用两个IN进行分组计数,然后生成数据比使用row_number进行选择的分区BY方法更快。

显然,你需要用500(或可能带有参数?)

+0

嗨乔纳森,所以如果我有第一个10条记录,它会显示所有的人。但我只需要每个组合的2个记录。 。谢谢。 – beginnerdscientist

+0

我编辑了代码,将每行限制为最多两条记录。我不确定每个组合的意思 - 我假设它意味着所有四个字段的组合,但是如果它少于四个,您应该能够看到如何将PARTITION BY更改为更少的字段。 –

+0

感谢乔纳森,我认为这应该工作。但我的桌子有几百万条记录,我需要每个cp和cid组合的大约500条记录。你认为这样做还是理想的吗? – beginnerdscientist