下面是一个名为Profile
AutoId | GroupId | ProfileId | ProfileName
-------------------------------------------------
239 | 54 | abcd | name1
251 | 44 | efgh | name2
255 | 54 | ijkl | name3
256 | 54 | mnop | name4
237 | 44 | qrst | name5
以下是名为Group
GroupId | IsLive
--------------------
44 | 1
54 | 0
我希望在IsLive
为1的记录中显示,然后以下记录将在IsLive
1和0的记录之间交替。例如。
AutoId | GroupId | ProfileId | ProfileName
--------------------------------------------------
237 | 44 | qrst | name5
251 | 44 | efgh | name2
255 | 54 | ijkl | name3
237 | 44 | qrst | name5
239 | 54 | abcd | name1
251 | 44 | efgh | name2
256 | 54 | mnop | name4
237 | 44 | qrst | name5
IsLive
= 1的记录如果超过IsLive
= 0,应该重复。到目前为止,我的查询已经
select AutoId, GroupId, ProfileId, ProfileName
from Profile
where GroupId in (select GroupId from Group where isnull(IsLive,0) = 1)
union all
select AutoId, GroupId, ProfileId, ProfileName
from Profile
where GroupId in (select GroupId from Group where isnull(IsLive,0) <> 1)
上面的查询在顶部给我IsLive
= 1,但我无法获得交替的行。任何帮助将不胜感激
答案 0 :(得分:1)
在问题之后,结果集应该有8行,在这种情况下是这个查询
WITH LiveRows AS (
SELECT p.AutoID, p.GroupId, p.ProfileID, p.ProfileName
, ID = Row_Number() OVER (ORDER BY p.AutoId) - 1
, Rows = COUNT(1) OVER (PARTITION BY NULL)
FROM [Profile] p
INNER JOIN [Group] g ON p.GroupId = g.GroupId
WHERE g.IsLive = 1
), DeadRows AS (
SELECT p.AutoID, p.GroupId, p.ProfileID, p.ProfileName
, ID = Row_Number() OVER (ORDER BY p.AutoId) - 1
FROM [Profile] p
INNER JOIN [Group] g ON p.GroupId = g.GroupId
WHERE g.IsLive = 0
), Ordered As (
SELECT d.AutoID
, ID = l.Rows + d.ID * 2
FROM DeadRows d
INNER JOIN LiveRows l ON l.ID = (d.ID % l.Rows)
UNION ALL
SELECT l.AutoID
, ID = l.Rows + (d.ID + 1) * 2 - 1
FROM DeadRows d
INNER JOIN LiveRows l ON l.ID = (d.ID % l.Rows)
), Total As (
Select p.AutoID, p.GroupId, p.ProfileID, p.ProfileName, p.ID
From LiveRows p
UNION ALL
Select p.AutoID, p.GroupId, p.ProfileID, p.ProfileName, o.ID
From Ordered o
INNER JOIN Profile p ON o.AutoID = p.AutoID
)
Select AutoID, GroupId, ProfileID, ProfileName
FROM Total
ORDER BY ID
会得到它。这并不容易,两个CTE
LiveRows和DeadRows用于增加可读性。
LiveRows和DeadRows在[Group]的isLive字段上过滤[Profile](对于表名真的是一个糟糕的选择),添加rownumber,并为实时数据添加行数。
行计数在Ordered中使用,连接两个子查询,并创建两行所需行数相同的缺失行。
在Ordered CTE
中还计算了将用于结果集的位置ID,因为它将以实时数据开始添加活动行数,公式的另一部分是奇数/偶数对。
总计CTE
将具有可用的全局排序字段
我不确定问题的最后两行来自哪里。
答案 1 :(得分:0)
交替值的基本查询是:
with lnl as (
select AutoId, GroupId, ProfileId, ProfileName,
row_number() over (partition by islive order by (select NULL)) as seqnum
from profiles p join
groups g
on p.groupid = g.groupid
)
select AutoId, GroupId, ProfileId, ProfileName
from lnl
order by seqnum, islive;
但是,这不会复制任何值,因此最后一行将是所有相同的类型。
我倾向于减少有效对的行数:
with lnl as (
select AutoId, GroupId, ProfileId, ProfileName,
row_number() over (partition by islive order by (select NULL)) as seqnum,
count(*) over (partition by islive) as cnt
from profiles p join
groups g
on p.groupid = g.groupid
),
cnts as (
select min(case when islive = 0 then cnt end) as livecnt,
min(case when islive = 1 then cnt end) as notlivecnt
from lnl
)
select AutoId, GroupId, ProfileId, ProfileName
from lnl join
cnts
on lnl.seqnum <= livecnt and lnl.seqnum <= notlivecnt
order by seqnum, islive;
复制要困难得多。其中一个问题是其中一个组可能没有任何行,这种可能性使逻辑复杂化。