SQL 仅在不同列中列出一次组合
SQL listing combinations in different columns only once
我的数据库如下所示
**Customer Order Product**
cid(PK) oid(PK) pid(PK)
fname cid(FK) pname
lname pid(FK) pprice
现在我正在使用查询来获得以下结果:
**fname lname oid pname pprice**
Bill Gates 1111 Router 40,-
Bill Gates 1112 Laptop 699,-
Steve Jobs 1113 Tablet 1299,-
Steve Jobs 1114 Watch 699,-
然而,我想要的是,如果此人有多个订单,则只列出一次名字和姓氏。我怎样才能做到这一点?
示例预期输出:
**fname lname oid pname pprice**
Bill Gates 1111 Router 40,-
1112 Laptop 699,-
Steve Jobs 1113 Tablet 1299,-
1114 Watch 699,-
在查询中使用 ROW_NUMBER() over(Partition by fname, Lname Order By Oid) 作为 RN 对行进行编号。然后在您的外部查询或下一个查询中,如果您将结果转储到临时 table,只要 RN 不为 1,就使用 case 语句将 fname 和 lname 设置为空字符串。
您需要一个额外的列,例如客户编号,以便您可以按客户编号、RN、Lname、Fname 进行订购
这个问题可以用LAG
函数解决。
LAG
函数 return 上一行给定列的值。
然后我们可以将前一行的值与当前行的值进行比较。
我们可以根据比较结果使用 CASE
语句来 return 值。
这是一个给出所需结果的查询:
SELECT
CASE
WHEN lag(concat(cop.fname, cop.lname), 1, 0) OVER (order by cop.oid) = concat(cop.fname, cop.lname) THEN null
ELSE cop.fname
END AS fname,
CASE
WHEN lag(concat(cop.fname, cop.lname), 1, 0) OVER (order by cop.oid) = concat(cop.fname, cop.lname) THEN null
ELSE cop.lname
END AS lname,
cop.oid,
cop.pname,
cop.pprice
FROM
(SELECT c.fname, c.lname, o.oid, p.pname, p.pprice
FROM customer c
LEFT JOIN myorder o on c.cid=o.cid
LEFT JOIN product p on o.pid=p.pid) cop
选择 ORDER
作为 table 的名称不是个好主意,因为 ORDER
是 SQL
中的关键字。所以我选择 MYORDER
作为包含订单的 table 的名称。
以上查询适用于 Oracle
数据库
我的数据库如下所示
**Customer Order Product**
cid(PK) oid(PK) pid(PK)
fname cid(FK) pname
lname pid(FK) pprice
现在我正在使用查询来获得以下结果:
**fname lname oid pname pprice**
Bill Gates 1111 Router 40,-
Bill Gates 1112 Laptop 699,-
Steve Jobs 1113 Tablet 1299,-
Steve Jobs 1114 Watch 699,-
然而,我想要的是,如果此人有多个订单,则只列出一次名字和姓氏。我怎样才能做到这一点?
示例预期输出:
**fname lname oid pname pprice**
Bill Gates 1111 Router 40,-
1112 Laptop 699,-
Steve Jobs 1113 Tablet 1299,-
1114 Watch 699,-
在查询中使用 ROW_NUMBER() over(Partition by fname, Lname Order By Oid) 作为 RN 对行进行编号。然后在您的外部查询或下一个查询中,如果您将结果转储到临时 table,只要 RN 不为 1,就使用 case 语句将 fname 和 lname 设置为空字符串。
您需要一个额外的列,例如客户编号,以便您可以按客户编号、RN、Lname、Fname 进行订购
这个问题可以用LAG
函数解决。
LAG
函数 return 上一行给定列的值。
然后我们可以将前一行的值与当前行的值进行比较。
我们可以根据比较结果使用 CASE
语句来 return 值。
这是一个给出所需结果的查询:
SELECT
CASE
WHEN lag(concat(cop.fname, cop.lname), 1, 0) OVER (order by cop.oid) = concat(cop.fname, cop.lname) THEN null
ELSE cop.fname
END AS fname,
CASE
WHEN lag(concat(cop.fname, cop.lname), 1, 0) OVER (order by cop.oid) = concat(cop.fname, cop.lname) THEN null
ELSE cop.lname
END AS lname,
cop.oid,
cop.pname,
cop.pprice
FROM
(SELECT c.fname, c.lname, o.oid, p.pname, p.pprice
FROM customer c
LEFT JOIN myorder o on c.cid=o.cid
LEFT JOIN product p on o.pid=p.pid) cop
选择 ORDER
作为 table 的名称不是个好主意,因为 ORDER
是 SQL
中的关键字。所以我选择 MYORDER
作为包含订单的 table 的名称。
以上查询适用于 Oracle
数据库