SQL Server不存在时如何插入?

时间:2018-12-19 07:31:51

标签: sql sql-server insert sql-server-2016

我有两个表,一个表称为“发票”,另一个表称为“记录”。

CREATE TABLE Invoices
(
    InvoiceNum INT NOT NULL,
    Amount DECIMAL,
    RecordPK UNIQUEIDENTIFIER NOT NULL
)

CREATE TABLE Records(
    RecordPK UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
    StartNum INT NOT NULL,
    NextNum INT NOT NULL,
    MaxNum INT NOT NULL,
    InvPrefix VARCHAR(2) NOT NULL
)

记录表将记录发票的起始编号,我们创建的发票数量(NextNum)和我们可以创建的发票数量(MaxNum)。

例如,假设我们在两个表中有几条记录。

发票表:

InvoiceNum    Amount    RecordPk
1             19.00     EDFA0541-5583-4CDD-BDFF-21D6F6504522
2             50.00     EDFA0541-5583-4CDD-BDFF-21D6F6504522
3             3.00      EDFA0541-5583-4CDD-BDFF-21D6F6504522
10            1.00      D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9
11            99.00     D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9
12            13.00     D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9

记录表:

RecordPk                                StartNum    NextNum    MaxNum    Prefix
EDFA0541-5583-4CDD-BDFF-21D6F6504522    1           4          10        AA
D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9    10          13         14        AA

我的问题是当我使用前缀AA搜索发票表时,如何获得如下所示的结果,InvoiceNum应该达到MaxNum,不存在的行的Amount和RecordPK应该保留为空白,Remark列应该填充为空白。

InvoiceNum    Amount    RecordPk                                Remark
1             19.00     EDFA0541-5583-4CDD-BDFF-21D6F6504522
2             50.00     EDFA0541-5583-4CDD-BDFF-21D6F6504522
3             3.00      EDFA0541-5583-4CDD-BDFF-21D6F6504522
4                                                               Blank
5                                                               Blank
6                                                               Blank
7                                                               Blank
8                                                               Blank
9                                                               Blank
10            1.00      D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9
11            99.00     D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9
12            13.00     D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9
13                                                              Blank
14                                                              Blank

4 个答案:

答案 0 :(得分:0)

您需要生成一个包含数字的表格,以覆盖所需的数字范围(对于Records表中的每一行,从StartNumMaxNum)。例如,您可以通过从现有表中选择足够的行并使用ROW_NUMBER窗口函数来执行此操作。然后过滤此序列以仅包含所需的数字。左联接Invoices表以显示相应发票的数据,并使用IIF函数检查是否有该编号的发票。

declare @Invoices table(InvoiceNum INT NOT NULL, Amount DECIMAL, RecordPK UNIQUEIDENTIFIER NOT NULL)
declare @Records table(RecordPK UNIQUEIDENTIFIER NOT NULL PRIMARY KEY, StartNum INT NOT NULL, NextNum INT NOT NULL, MaxNum INT NOT NULL, InvPrefix VARCHAR(2) NOT NULL)

insert into @Invoices(InvoiceNum, Amount, RecordPk) values
(1 ,            19.00,    'EDFA0541-5583-4CDD-BDFF-21D6F6504522'),
(2 ,            50.00,    'EDFA0541-5583-4CDD-BDFF-21D6F6504522'),
(3 ,            3.00 ,    'EDFA0541-5583-4CDD-BDFF-21D6F6504522'),
(10,            1.00 ,    'D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9'),
(11,            99.00,    'D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9'),
(12,            13.00,    'D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9')

insert into @Records(RecordPk, StartNum, NextNum, MaxNum, InvPrefix) values
('EDFA0541-5583-4CDD-BDFF-21D6F6504522',    1 ,          4 ,         10,        'AA'),
('D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9',    10,          13,         14,        'AA')

;with numbers as (select ROW_NUMBER() over(order by object_id) as No from sys.objects)
select
    n.No as InvoiceNum
    , inv.Amount
    , inv.RecordPK
    , IIF(inv.InvoiceNum is null, 'Blank', null) as Remark
from numbers n
left join @Invoices inv on n.No = inv.InvoiceNum
where exists(select * from @Records r where r.StartNum <= n.No and n.No <= r.MaxNum)

答案 1 :(得分:0)

您需要左加入

class ViewController: UIViewController {

    lazy var barButton: ButtonWithProperty = {
        let button = ButtonWithProperty()
        ... // color, title, target, etc.
        return button
    }()

    ...

    override func viewDidLoad() {
        super.viewDidLoad()
        ...
        guard let navigationBar = self.navigationController?.navigationBar else { return }

        navigationBar.addSubview(barButton)
        barButton.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            barButton.rightAnchor.constraint(equalTo: navigationBar.rightAnchor, constant: -20),
            barButton.bottomAnchor.constraint(equalTo: navigationBar.bottomAnchor, constant: -6)
        ])

    }
    ...
}

try{ axios.get("https://api.neoscan.io/api/main_net/v1/get_all_nodes") .then(data => res.status(200).send(data)) .catch(err => res.send(err)); } catch(err){ console.error("GG", err); } SELECT I.*, CASE WHEN I.InvoiceNum IS NULL THEN 'Blank' END Remark FROM (VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12), (13), (14)) RC (InvoiceNum) LEFT JOIN Invoices I ON RC.InvoiceNum = I.InvoiceNum; ,而值1是最大值StartNum。 我使用了VALUES,因为知道该数字,您可以使用RecursiveCTE生成丢失的14,然后将LEFT JOIN与表一起使用。

Demo

答案 2 :(得分:0)

@Andrey Nikolov报道了它,但是最近15分钟我一直在进行此工作,因此我认为无论如何都要发布它。

基本上,应该使用中介表来计算您没有的值,然后在此答案的我的版本中,我使用了联合查询来生成“空白”值。为了简洁起见,我没有包含唯一标识符,但是应用程序是相同的。

if OBJECT_ID('tempdb..#invoice') is not null drop table #invoice;
if OBJECT_ID('tempdb..#rowcount') is not null drop table #rowcount;

create table #invoice
    (
        invoicenum int,
        amount decimal
    );


insert into #invoice (invoicenum, amount)
values
(1, 19.00),
(2, 50.00),
(3, 3.00),
(10, 1.00),
(11, 99.00),
(12, 13.00);


create table #rowcount

    (
        rownumber int 
    );

declare @max int = 1;

select @max=count(*) from #invoice;

declare @runs int = 1;

while @runs<=@max
begin
insert into #rowcount (rownumber)
values (@runs);
select @runs=@runs+1;
end


select invoicenum, cast(amount as nvarchar(25)) as amount from #invoice
union
select rownumber, 'BLANK' from #rowcount r left join #invoice i on 
r.rownumber=i.invoicenum where i.invoicenum is null
order by invoicenum;

drop table #invoice, #rowcount;

答案 3 :(得分:0)

我会这样:

    IF OBJECT_ID('tempdb..#Invoices') IS NOT NULL DROP TABLE #Invoices

    CREATE TABLE #Invoices
    (
        InvoiceNum INT NOT NULL,
        Amount DECIMAL,
        RecordPK UNIQUEIDENTIFIER NOT NULL
    )

    IF OBJECT_ID('tempdb..#Records') IS NOT NULL DROP TABLE #Records

    CREATE TABLE #Records(
        RecordPK UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
        StartNum INT NOT NULL,
        NextNum INT NOT NULL,
        MaxNum INT NOT NULL,
        InvPrefix VARCHAR(2) NOT NULL
    )

    INSERT INTO #Invoices
    SELECT 1, 19.00, 'EDFA0541-5583-4CDD-BDFF-21D6F6504522'
    UNION SELECT 2 , 50.00, 'EDFA0541-5583-4CDD-BDFF-21D6F6504522'
    UNION SELECT 3 , 3.00 , 'EDFA0541-5583-4CDD-BDFF-21D6F6504522'
    UNION SELECT 10 , 1.00 , 'D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9'
    UNION SELECT 11 , 99.00, 'D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9'
    UNION SELECT 12 , 13.00, 'D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9'

    INSERT INTO #Records
    SELECT 'EDFA0541-5583-4CDD-BDFF-21D6F6504522', 1, 4, 10, 'AA'
    UNION SELECT 'D64EFF0E-65D5-467E-8C82-BFBB6A24AAC9', 10, 13, 14, 'AA'

    DECLARE @MAX_NUM INT = (SELECT MAX(MaxNum) FROM #Records)
    DECLARE @TEMP_INV TABLE (InvoiceNum INT)
    INSERT INTO @TEMP_INV
    SELECT Num
    FROM
    (
        SELECT ROW_NUMBER() OVER(ORDER BY object_id) AS Num FROM sys.objects
    ) A
    WHERE Num <= @MAX_NUM

    IF OBJECT_ID('tempdb..#TEMP') IS NOT NULL DROP TABLE #TEMP

    SELECT I.InvoiceNum, I.Amount, I.RecordPK
    INTO #TEMP
    FROM #Invoices I
    INNER JOIN #Records R
        ON I.RecordPK = R.RecordPK
    WHERE R.InvPrefix = 'AA'

    SELECT A.InvoiceNum, B.Amount, B.RecordPK, CASE WHEN B.InvoiceNum IS NULL THEN 'BLANK' END AS Remark
    FROM @TEMP_INV A
    LEFT JOIN #TEMP B
        ON A.InvoiceNum = B.InvoiceNum