Sql 如何将表与其自身联接并将其显示为一行

Sql 如何将表与其自身联接并将其显示为一行,sql,sql-server,Sql,Sql Server,有一个名为PRODUCT_PRICE的表: CREATE TABLE [TEST].[PRODUCT_PRICE] ( [PRICE_ID] [bigint] NOT NULL, [PRODUCT_ID] [bigint] NOT NULL, [PRICE_DATE] [date] NOT NULL, [IS_SALE_PRICE] [bit] NOT NULL, [UNIT_PRICE] [decimal](18, 2) NOT NULL ) 它有以下

有一个名为PRODUCT_PRICE的表:

CREATE TABLE [TEST].[PRODUCT_PRICE]
(
    [PRICE_ID] [bigint] NOT NULL,
    [PRODUCT_ID] [bigint] NOT NULL,
    [PRICE_DATE] [date] NOT NULL,
    [IS_SALE_PRICE] [bit] NOT NULL,
    [UNIT_PRICE] [decimal](18, 2) NOT NULL
)
它有以下记录:

PRICE_ID PRODUCT_ID PRICE_DATE  IS_SALE_PRICE UNIT_PRICE
-------- ---------- ----------  ------------- ----------
1        15         2015-05-12  False         0,05
2        15         2015-05-12  True          0,04
3        25         2015-05-12  False         1,45
4        35         2015-05-12  True          2,65
编辑:只能有两个价格-购买价格和销售价格。不能有3行或更多行具有相同的
产品ID
价格日期

我想写一个
SELECT
语句,结果如下:

PRICE_ID PRODUCT_ID PRICE_DATE  IS_SALE_PRICE UNIT_PRICE PRICE_ID_2 IS_SALE_PRICE_2 UNIT_PRICE_2
-------- ---------- ----------  ------------- ---------- ---------- --------------- ------------
1        15         2015-05-12  False         0,05       2          True            0,04
3        25         2015-05-12  False         1,45       NULL       NULL            NULL
4        35         2015-05-12  True          2,65       NULL       NULL            NULL
我尝试了
完全外部联接
,但结果是4行而不是3行,这是正确的,但不是我想要的:

SELECT
    PR1.*,
    PR2.PRICE_ID AS PRICE_ID_2,
    PR2.IS_SALE_PRICE AS IS_SALE_PRICE_2,
    PR2.UNIT_PRICE AS UNIT_PRICE_2
FROM PRODUCT_PRICE AS PR1
FULL OUTER JOIN PRODUCT_PRICE AS PR2
    ON PR1.PRODUCT_ID = PR2.PRODUCT_ID
    AND PR1.PRICE_DATE = PR2.PRICE_DATE
    AND PR1.PRICE_ID <> PR2.PRICE_ID
    AND PR1.IS_SALE_PRICE <> PR2.IS_SALE_PRICE
WHERE
    PR1.PRICE_DATE = '20150512'
ORDER BY PR1.PRICE_ID
基本上,我想
将一个表与其自身连接起来并删除重复项

注意:
PRICE\u ID
是一个
identity
字段(主键)。但是自然的关键是
产品ID
价格日期
对。我希望为每个唯一的
产品标识
价格日期
指定一行


您将获得
PRICE\u ID=1
vs
PRICE\u ID=2
PRICE\u ID=2
vs
PRICE\u ID=1
所以你有一个重复的行

ON子句
中,当
PRICE\u ID1

在ON条款中添加以下内容:

AND PR1.PRICE_ID < PR2.PRICE_ID

您将获得
PRICE\u ID=1
vs
PRICE\u ID=2
PRICE\u ID=2
vs
PRICE\u ID=1
所以你有一个重复的行

ON子句
中,当
PRICE\u ID1

在ON条款中添加以下内容:

AND PR1.PRICE_ID < PR2.PRICE_ID

您将获得
PRICE\u ID=1
vs
PRICE\u ID=2
PRICE\u ID=2
vs
PRICE\u ID=1
所以你有一个重复的行

ON子句
中,当
PRICE\u ID1

在ON条款中添加以下内容:

AND PR1.PRICE_ID < PR2.PRICE_ID

您将获得
PRICE\u ID=1
vs
PRICE\u ID=2
PRICE\u ID=2
vs
PRICE\u ID=1
所以你有一个重复的行

ON子句
中,当
PRICE\u ID1

在ON条款中添加以下内容:

AND PR1.PRICE_ID < PR2.PRICE_ID

执行
完全外部联接

select ...
from PRODUCT_PRICE p1
  FULL OUTER JOIN PRODUCT_PRICE p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE
    AND p1.IS_SALE_PRICE = 'true
    AND p2.IS_SALE_PRICE = 'false'
写入选择列表列。调整就是销售和价格比较

替代解决方案,派生表
完全外部联接

select ...
from (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'true') as p1
  FULL OUTER JOIN
     (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'false') as p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE

执行
完全外部联接

select ...
from PRODUCT_PRICE p1
  FULL OUTER JOIN PRODUCT_PRICE p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE
    AND p1.IS_SALE_PRICE = 'true
    AND p2.IS_SALE_PRICE = 'false'
写入选择列表列。调整就是销售和价格比较

替代解决方案,派生表
完全外部联接

select ...
from (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'true') as p1
  FULL OUTER JOIN
     (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'false') as p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE

执行
完全外部联接

select ...
from PRODUCT_PRICE p1
  FULL OUTER JOIN PRODUCT_PRICE p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE
    AND p1.IS_SALE_PRICE = 'true
    AND p2.IS_SALE_PRICE = 'false'
写入选择列表列。调整就是销售和价格比较

替代解决方案,派生表
完全外部联接

select ...
from (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'true') as p1
  FULL OUTER JOIN
     (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'false') as p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE

执行
完全外部联接

select ...
from PRODUCT_PRICE p1
  FULL OUTER JOIN PRODUCT_PRICE p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE
    AND p1.IS_SALE_PRICE = 'true
    AND p2.IS_SALE_PRICE = 'false'
写入选择列表列。调整就是销售和价格比较

替代解决方案,派生表
完全外部联接

select ...
from (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'true') as p1
  FULL OUTER JOIN
     (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'false') as p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE

如果您确定每个
PRODUCT\u ID
-
PRICE\u DATE
组合最多只能有2行,则可以使用条件聚合而不是
JOIN

select ...
from (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'true') as p1
  FULL OUTER JOIN
     (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'false') as p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE

结果

| PRICE_ID | PRODUCT_ID | PRICE_DATE | IS_SALE_PRICE | UNIT_PRICE | PRICE_ID2 | IS_SALE_PRICE2 | UNIT_PRICE2 |
|----------|------------|------------|---------------|------------|-----------|----------------|-------------|
|        1 |         15 | 2015-05-12 |             0 |       0.05 |         2 |              1 |        0.04 |
|        3 |         25 | 2015-05-12 |             0 |       1.45 |    (null) |         (null) |      (null) |
|        4 |         35 | 2015-05-12 |             1 |       2.65 |    (null) |         (null) |      (null) |

如果您坚持使用
加入
,您可以使用
完全加入

select ...
from (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'true') as p1
  FULL OUTER JOIN
     (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'false') as p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE


如果您确定每个
PRODUCT\u ID
-
PRICE\u DATE
组合最多只能有2行,则可以使用条件聚合而不是
JOIN

select ...
from (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'true') as p1
  FULL OUTER JOIN
     (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'false') as p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE

结果

| PRICE_ID | PRODUCT_ID | PRICE_DATE | IS_SALE_PRICE | UNIT_PRICE | PRICE_ID2 | IS_SALE_PRICE2 | UNIT_PRICE2 |
|----------|------------|------------|---------------|------------|-----------|----------------|-------------|
|        1 |         15 | 2015-05-12 |             0 |       0.05 |         2 |              1 |        0.04 |
|        3 |         25 | 2015-05-12 |             0 |       1.45 |    (null) |         (null) |      (null) |
|        4 |         35 | 2015-05-12 |             1 |       2.65 |    (null) |         (null) |      (null) |

如果您坚持使用
加入
,您可以使用
完全加入

select ...
from (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'true') as p1
  FULL OUTER JOIN
     (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'false') as p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE


如果您确定每个
PRODUCT\u ID
-
PRICE\u DATE
组合最多只能有2行,则可以使用条件聚合而不是
JOIN

select ...
from (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'true') as p1
  FULL OUTER JOIN
     (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'false') as p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE

结果

| PRICE_ID | PRODUCT_ID | PRICE_DATE | IS_SALE_PRICE | UNIT_PRICE | PRICE_ID2 | IS_SALE_PRICE2 | UNIT_PRICE2 |
|----------|------------|------------|---------------|------------|-----------|----------------|-------------|
|        1 |         15 | 2015-05-12 |             0 |       0.05 |         2 |              1 |        0.04 |
|        3 |         25 | 2015-05-12 |             0 |       1.45 |    (null) |         (null) |      (null) |
|        4 |         35 | 2015-05-12 |             1 |       2.65 |    (null) |         (null) |      (null) |

如果您坚持使用
加入
,您可以使用
完全加入

select ...
from (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'true') as p1
  FULL OUTER JOIN
     (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'false') as p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE


如果您确定每个
PRODUCT\u ID
-
PRICE\u DATE
组合最多只能有2行,则可以使用条件聚合而不是
JOIN

select ...
from (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'true') as p1
  FULL OUTER JOIN
     (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'false') as p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE

结果

| PRICE_ID | PRODUCT_ID | PRICE_DATE | IS_SALE_PRICE | UNIT_PRICE | PRICE_ID2 | IS_SALE_PRICE2 | UNIT_PRICE2 |
|----------|------------|------------|---------------|------------|-----------|----------------|-------------|
|        1 |         15 | 2015-05-12 |             0 |       0.05 |         2 |              1 |        0.04 |
|        3 |         25 | 2015-05-12 |             0 |       1.45 |    (null) |         (null) |      (null) |
|        4 |         35 | 2015-05-12 |             1 |       2.65 |    (null) |         (null) |      (null) |

如果您坚持使用
加入
,您可以使用
完全加入

select ...
from (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'true') as p1
  FULL OUTER JOIN
     (select * from PRODUCT_PRICE
      where  IS_SALE_PRICE = 'false') as p2
    ON  p1.PRODUCT_ID = p2.PRODUCT_ID
    AND p1.PRICE_DATE = p2.PRICE_DATE


您希望每个产品标识对应一行吗?如果有3个(或4个)价格ID与相同的产品ID相同,您希望得到什么结果?@TimSchmelter Done,添加到末尾。为什么在关门时这么咄咄逼人?已经有2票接近。我试着尽可能简单地解释。你真的需要
PRICE\u ID
?我认为这可以通过动态交叉表来完成。@jarlh添加了“注意”部分。@AnarKhalilov,我已经编辑了您的问题,并用sql FIDLE替换了图像。您希望每个产品ID对应一行吗?如果有3个(或4个)价格ID与相同的产品ID相同,您希望得到什么结果?@TimSchmelter Done,添加到末尾。为什么在关门时这么咄咄逼人?已经有2票接近。我试着尽可能简单地解释。你真的需要
PRICE\u ID
?我认为这可以通过动态交叉表来完成。@jarlh添加了“注意”部分。@AnarKhalilov,我已经编辑了您的问题,并用sql FIDLE替换了图像。您希望每个产品ID对应一行吗?如果有3个(或4个)价格ID与相同的产品ID相同,您希望得到什么结果?@TimSchmelter Done,添加到末尾。为什么在关门时这么咄咄逼人?已经有2票接近。我试着尽可能简单地解释。你真的需要
PRICE\u ID
?我认为这可以通过动态交叉表来完成。@jarlh添加了“注意”部分。@AnarKhalilov,我已经编辑了您的问题,并用sql FIDLE替换了图像。您希望每个产品ID对应一行吗?如果有3个(或4个)价格ID与相同的产品ID相同,您希望得到什么结果?@TimSchmelter Done,添加到末尾。为什么在关门时这么咄咄逼人?已经有2票接近。我试着尽可能简单地解释。你真的需要
PRICE\u ID
?我认为这可以通过动态交叉表来完成。@jarlh添加了“注意”部分。@AnarKhal