“Stuff and 'For Xml Path'” 或 UNION 以排除重复行

如何解决“Stuff and 'For Xml Path'” 或 UNION 以排除重复行

这是问题的进一步进展:how to use "Stuff and 'For Xml Path'" to unite rows in table

我有 3 个表 - 发票、头寸和帐户,它们通过 SELECT 构建通用表,如下面的结果所示。我需要排除由于相同发票的不同帐户而出现的重复行。我认为它可以通过“Stuff and 'For Xml Path'”和/或 UNION 来解决,但我真的不知道该怎么做。

请协助解决此问题。提前致谢。

这是包含 DL 和样本数据群的 dbfiddle:https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=6401c2886a24b21239dade27e8c549ec

使用基于 SQL Server 2016 的 DevExpress 仪表板设计器。

查询:

-- DDL and sample data population,start
CREATE TABLE invoices
(
invoice VARCHAR(20) NOT NULL,id INT NOT NULL,);
INSERT invoices(invoice,id) 
VALUES ('ty20210110',1);
INSERT invoices(invoice,id) 
VALUES ('ty20210111',2);
INSERT invoices(invoice,id) 
VALUES ('ty20210112',3);

CREATE TABLE positions
(
position VARCHAR(20) NOT NULL,quantity INT NOT NULL,price INT NOT NULL,summ INT NOT NULL,invoice INT NOT NULL,);
INSERT positions(position,quantity,price,summ,invoice) 
VALUES ('p1000001',2,100,200,1);
INSERT positions(position,invoice) 
VALUES ('p1000002',3,300,2);
INSERT positions(position,invoice) 
VALUES ('p1000003',1,250,invoice) 
VALUES ('p1000004',120,240,invoice) 
VALUES ('p1000005',4,400,invoice) 
VALUES ('p1000006',1001);
INSERT positions(position,invoice) 
VALUES ('p1000007',5,80,3);
INSERT positions(position,invoice) 
VALUES ('p1000008',500,3);

CREATE TABLE accounts
(
account INT NOT NULL,);
INSERT accounts(account,invoice) 
VALUES (01,2);
INSERT accounts(account,invoice) 
VALUES (02,invoice) 
VALUES (03,1);
INSERT accounts(account,invoice) 
VALUES (04,3);
INSERT accounts(account,invoice) 
VALUES (05,invoice) 
VALUES (06,3);
-- DDL and sample data population,end


SELECT
positions.position,positions.quantity,positions.price,positions.summ,invoices.invoice,accounts.account

FROM
positions
INNER JOIN
invoices invoices ON invoices.id = positions.invoice
INNER JOIN
accounts accounts ON invoices.id = accounts.invoice

结果:

位置 数量 价格 总和 发票 帐号
p1000001 2 100 200 in20210110 3
p1000001 2 100 200 in20210110 5
p1000002 3 100 300 in20210111 1
p1000002 3 100 300 in20210111 2
p1000003 1 250 250 in20210111 1
p1000003 1 250 250 in20210111 2
p1000004 2 120 240 in20210110 3
p1000004 2 120 240 in20210110 5
p1000005 4 100 400 in20210110 3
p1000005 4 100 400 in20210110 5
p1000006 3 100 300 in20210110 3
p1000006 3 100 300 in20210110 5
p1000007 5 80 400 in20210112 4
p1000007 5 80 400 in20210112 6
p1000008 5 100 500 in20210112 4
p1000008 5 100 500 in20210112 6

要求的结果 1:

位置 数量 价格 总结 发票 帐号
p1000001 2 100 200 in20210110 3、5
p1000004 2 120 240 in20210110 3、5
p1000005 4 100 400 in20210110 3、5
p1000006 3 100 300 in20210110 3、5
p1000002 3 100 300 in20210111 1、2
p1000003 1 250 250 in20210111 1、2
p1000007 5 80 400 in20210112 4、6
p1000008 5 100 500 in20210112 4、6

要求的结果 2:

位置 数量 价格 总和 发票 帐号 1 帐号 2
p1000001 2 100 200 in20210110 3 5
p1000004 2 120 240 in20210110 3 5
p1000005 4 100 400 in20210110 3 5
p1000006 3 100 300 in20210110 3 5
p1000002 3 100 300 in20210111 1 2
p1000003 1 250 250 in20210111 1 2
p1000007 5 80 400 in20210112 4 6
p1000008 5 100 500 in20210112 4 6

解决方法

您的第一个结果集可以通过两种方式处理,具体取决于您的 SQL Server 版本。在 SSMS 中尝试以下示例:

创建数据

DECLARE @invoices table (
    invoice VARCHAR(20) NOT NULL,id INT NOT NULL 
);

INSERT INTO @invoices (invoice,id) VALUES 
    ( 'ty20210110',1 ),( 'ty20210111',2 ),( 'ty20210112',3 );

DECLARE @positions table (
    position VARCHAR(20) NOT NULL,quantity INT NOT NULL,price INT NOT NULL,summ INT NOT NULL,invoice INT NOT NULL
);

INSERT INTO @positions ( position,quantity,price,summ,invoice ) VALUES
    ( 'p1000001',2,100,200,( 'p1000002',3,300,( 'p1000003',1,250,( 'p1000004',120,240,( 'p1000005',4,400,( 'p1000006',( 'p1000007',5,80,3 ),( 'p1000008',500,3 );

DECLARE @accounts table (
    account INT NOT NULL,invoice INT NOT NULL
);

INSERT INTO @accounts ( account,invoice ) VALUES 
    ( 1,( 2,( 3,( 4,( 5,( 6,3 );

如果您使用的是 SQL Server 2017+

SELECT
    positions.position,positions.quantity,positions.price,positions.summ,invoices.invoice,STRING_AGG ( accounts.account,',' ) AS account
FROM @positions positions
INNER JOIN @invoices invoices 
    ON invoices.id = positions.invoice
INNER JOIN @accounts accounts 
    ON invoices.id = accounts.invoice
GROUP BY
    position,invoices.invoice
ORDER BY
    invoice;

对于 Pre-SQL Server 2017

SELECT
    positions.position,acct.account
FROM @positions positions
INNER JOIN @invoices invoices 
    ON invoices.id = positions.invoice
INNER JOIN @accounts accounts 
    ON invoices.id = accounts.invoice
OUTER APPLY (
    SELECT STUFF ( (
        SELECT ',' + CAST ( a.account AS varchar(50) ) AS "text()"
        FROM @accounts a
        WHERE
            a.invoice = invoices.id
        FOR XML PATH ( '' )
    ),'' ) AS account
) AS acct
GROUP BY
    position,acct.account
ORDER BY
    invoice;

两个查询都返回

+----------+----------+-------+------+------------+---------+
| position | quantity | price | summ |  invoice   | account |
+----------+----------+-------+------+------------+---------+
| p1000001 |        2 |   100 |  200 | ty20210110 | 3,5     |
| p1000004 |        2 |   120 |  240 | ty20210110 | 3,5     |
| p1000005 |        4 |   100 |  400 | ty20210110 | 3,5     |
| p1000006 |        3 |   100 |  300 | ty20210110 | 3,5     |
| p1000002 |        3 |   100 |  300 | ty20210111 | 1,2     |
| p1000003 |        1 |   250 |  250 | ty20210111 | 1,2     |
| p1000007 |        5 |    80 |  400 | ty20210112 | 4,6     |
| p1000008 |        5 |   100 |  500 | ty20210112 | 4,6     |
+----------+----------+-------+------+------------+---------+

您请求的第二个结果集变得相当复杂,并且需要使用 XML 数据类型。以下示例对您的数据进行了自由假设,最明显的是只需要两个帐户。话虽如此,您可以根据需要扩展 [account n] 中的 PIVOT 列,而不必求助于动态 SQL。

SELECT DISTINCT
    positions.position,x.*
FROM @positions positions
INNER JOIN @invoices invoices 
    ON invoices.id = positions.invoice
INNER JOIN @accounts accounts 
    ON invoices.id = accounts.invoice
OUTER APPLY (

    -- Create an XML account list --
    SELECT CAST ( (
        SELECT 
            'account ' + CAST ( ROW_NUMBER() OVER ( ORDER BY a.invoice ) AS varchar(50) ) AS id,a.account
        FROM @accounts a
        WHERE
            a.invoice = invoices.id
        FOR XML PATH ( 'data' ),ROOT ( 'accounts' )
    ) AS xml ) AS account_xml

) AS acct
OUTER APPLY (

    -- PIVOT the account details --
    SELECT
        *
    FROM (
        SELECT
            x.f.value( 'id[1]','varchar(50)' ) AS id,x.f.value( 'account[1]','varchar(50)' ) AS act
        FROM acct.account_xml.nodes( '//accounts/data' ) x(f)
    ) AS d
    PIVOT (
        MAX ( act ) FOR id IN ( [account 1],[account 2] )
    ) AS p

) AS x
ORDER BY
    invoice;

退货

+----------+----------+-------+------+------------+-----------+-----------+
| position | quantity | price | summ |  invoice   | account 1 | account 2 |
+----------+----------+-------+------+------------+-----------+-----------+
| p1000001 |        2 |   100 |  200 | ty20210110 |         3 |         5 |
| p1000004 |        2 |   120 |  240 | ty20210110 |         3 |         5 |
| p1000005 |        4 |   100 |  400 | ty20210110 |         3 |         5 |
| p1000006 |        3 |   100 |  300 | ty20210110 |         3 |         5 |
| p1000002 |        3 |   100 |  300 | ty20210111 |         1 |         2 |
| p1000003 |        1 |   250 |  250 | ty20210111 |         1 |         2 |
| p1000007 |        5 |    80 |  400 | ty20210112 |         4 |         6 |
| p1000008 |        5 |   100 |  500 | ty20210112 |         4 |         6 |
+----------+----------+-------+------+------------+-----------+-----------+

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-