Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 按行值划分_Sql Server_Database_Tsql - Fatal编程技术网

Sql server 按行值划分

Sql server 按行值划分,sql-server,database,tsql,Sql Server,Database,Tsql,当某一行具有某一值时,我需要对输出表进行分区。我有: ID|Value|User ------------- 1 |A |Rick 2 |A |Rick 3 |B |Rick 7 |A |Rick 8 |C |Rick 4 |A |Joe 5 |B |Joe 6 |B |Joe 我需要为每个单独的用户对表进行分区,当值=A时,我需要的是: Row|ID|Value|User ------------------ 1 |1 |A |Rick

当某一行具有某一值时,我需要对输出表进行分区。我有:

ID|Value|User
-------------
1 |A    |Rick
2 |A    |Rick
3 |B    |Rick
7 |A    |Rick
8 |C    |Rick
4 |A    |Joe
5 |B    |Joe
6 |B    |Joe
我需要为每个单独的用户对表进行分区,当值=A时,我需要的是:

Row|ID|Value|User
------------------
1  |1 |A    |Rick 
1  |2 |A    |Rick
2  |3 |B    |Rick
1  |7 |A    |Rick
2  |8 |C    |Rick
1  |4 |A    |Joe
2  |5 |B    |Joe
3  |6 |B    |Joe
每个值都有自己的ID

我试过这样的方法:

SELECT ROW_NUMBER() OVER(PARTITION BY User, Value = A ORDER BY ID ASC) AS Row, Value, User FROM...
SELECT ROW_NUMBER() OVER(PARTITION BY User, WHERE Value = A ORDER BY ID ASC) AS Row, Value, User FROM...
etc

但是,如果可能的话,我似乎不知道如何正确地书写它。

似乎你想要的只是一个密集的等级:

注意用户是T-SQL中的保留关键字。我强烈建议您为列选择不同的名称,否则您必须对其进行分隔和标识。行和值当前未保留,但它们列为,建议避免使用

编辑:看起来,实际上它的'A'是1,然后也会增加。这很混乱,但你可以这样做:

SELECT CASE [Value]
            WHEN 'A' THEN 1
            ELSE ROW_NUMBER() OVER (PARTITION BY [User] ORDER BY [Value]) -
                 COUNT(CASE [Value] WHEN 'A' THEN 1 END) OVER (PARTITION BY [User]) + 1
       END AS [Row],
       V.[Value],
       V.[User]
FROM (VALUES ('A', 'Rick'),
             ('A', 'Rick'),
             ('B', 'Rick'),
             ('C', 'Rick'),
             ('A', 'Joe '),
             ('B', 'Joe '),
             ('B', 'Joe ')) V ([Value], [User]);
这假定始终至少有一行带有“A”

编辑2:好的,目标帖子又被移动了,这就是你想要的。如果他们再次移动,您需要修改解决方案,但:

WITH YourTable AS(
    SELECT V.ID,
           V.Value,
           V.[User]
    FROM (VALUES(1,'A','Rick'),
                (2,'A','Rick'),
                (3,'B','Rick'),
                (7,'A','Rick'),
                (8,'C','Rick'),
                (4,'A','Joe '),
                (5,'B','Joe '),
                (6,'B','Joe '))V(ID,[Value],[User])),
Grps AS(
    SELECT YT.ID,
           YT.Value,
           YT.[User],
           COUNT(CASE YT.[Value] WHEN 'A' THEN 1 END) OVER(PARTITION BY YT.[User] ORDER BY YT.ID) AS Grp
    FROM YourTable YT)
SELECT ID,
       CASE G.[Value]
            WHEN 'A' THEN 1
            ELSE ROW_NUMBER() OVER (PARTITION BY G.[User], G.Grp ORDER BY G.[Value]) -
                 COUNT(CASE G.[Value] WHEN 'A' THEN 1 END) OVER (PARTITION BY G.[User], G.Grp) + 1
       END AS [Row],
       G.[Value],
       G.[User]
FROM Grps G
ORDER BY G.[User], G.ID;

这个怎么样-A总是1,如果出现A,我将行卷回1,如果不是A,我总是增加1

With CTE AS (select *, row_number() OVER (order by [user], value) as RN from theTable)

select CASE WHEN C1.Value = 'A' THEN 1 ELSE 1 +  C1.RN - C.RN  END [row] ,  * from 
            CTE C1 OUTER APPLY 
              (SELECT TOP 1 RN FROM CTE C2 
                                WHERE C2.RN < C1.RN AND C2.Value = 'A' 
                                ORDER BY C2.RN DESC) C
我不认为稠密秩会像你的例子中那样工作,B会有相同的值

2  |B    |Joe
2  |B    |Joe
而不是

2  |B    |Joe
3  |B    |Joe
我想出的最好的方法是两遍法

使用普通行号->按c.name按c.value按顺序划分的行号作为rn 然后使用densite_-RANK->densite_-RANK按c.名称顺序按IIFc.值='a',NULL,c.rn划分 这里的技巧是根据条件IIFc.value='a',NULL,c.rn将其设为NULL的顺序
不完全是这样,例如Joe的值是B的两倍,但Row应该保持递增。或者,有没有一种方法可以通过密集排列来实现这一点?此外,我在这里为我的行使用假名称,不需要担心用户行名称。不过还是要谢谢你的提醒!所以在“A”处总是1,然后不管怎样递增,@PAT_The_Whale?混乱,但基于这种逻辑,底部的版本是有效的。它对我有效,@PAT_The_Whale:。为什么我包括DDL和DML。如果不是,那么你就没有告诉我们什么。你已经补充了另一个答案,@PAT_The_Whale。请不要再移动目标柱。你想要什么的逻辑是什么?从你的数据中我可以看到A和Rick是1,A和Joe也是1。怎么会这样?你什么意思?如果你需要它,你可以想象它的价值,就像是法拉利或者其他什么车型。问题已经改变了,这是不可能的。您的数据中没有任何内容可以使用order BY来维护其顺序。表本身是无序的,因此在您的问题中,表中A“B”下方出现的“A”可能位于表中的任何位置。每个值都有一个唯一的ID,这可能吗?我看不出这可能,因为您没有按顺序显示ID,这意味着您需要某种其他类型的顺序—您在其中显示记录的顺序是什么?如果源表中有另一列,如标识,并且您希望该顺序是这样的,则可以跳过cte_添加_简单_顺序,直接使用该顺序。按c.名称顺序按IIFc.值='a',NULL,唯一顺序或列我认为你的方法行不通。它不仅在900行的4,30分钟内非常慢,而且行数有时会从1跳到8,例如,尽管用户只有2个值
2  |B    |Joe
2  |B    |Joe
2  |B    |Joe
3  |B    |Joe
WITH 
    cte_dataset ([value], [name])
  AS (SELECT 'A' AS v, 'Rick' AS n
      UNION ALL
      SELECT 'A' AS v, 'Rick' AS n
      UNION ALL
      SELECT 'B' AS v, 'Rick' AS n
      UNION ALL
      SELECT 'C' AS v, 'Rick' AS n
      UNION ALL
      SELECT 'A' AS v, 'Joe' AS n
      UNION ALL
      SELECT 'B' AS v, 'Joe' AS n
      UNION ALL
      SELECT 'B' AS v, 'Joe' AS n)
   , cte_add_simple_order
  AS (
    SELECT 
        c.value, 
        c.name, 
        ROW_NUMBER() OVER (PARTITION BY c.name ORDER BY c.value) AS rn 
    FROM cte_dataset c
    )
SELECT
    c.value
  , c.name
  , DENSE_RANK() OVER (PARTITION BY c.name ORDER BY IIF(c.value = 'a', NULL, c.rn))
FROM cte_add_simple_order c
ORDER BY
    c.name DESC
  , c.value ;
|value|name|Rank|
|A    |Rick|1   |
|A    |Rick|1   |
|B    |Rick|2   |
|C    |Rick|3   |
|A    |Joe |1   |
|B    |Joe |2   |
|B    |Joe |3   |