I am re-writing an export script that was run in our old flat database into our new normalized structure. In the past we had a table called Case that had three columns for owner name info - Ownername1, Ownername2 and Ownername3. Now, we have zero-to-many debtors, and instead of having one row with up to three owners we have a row for each owner. I am having to massage this into an export that will be used in an Excel spreadsheet that the client is using, but I have to "dumb down" the structure to fit it back into that flat structure. I need to grab the names of the owners of the first three rows and concatenate the first and last name. I have been playing around with (SELECT ROW_NUMBER() OVER and it looks like the solution but I can't get it to work properly for my case. I not only need to concatenate the first and last names, but I also need to coalesce them to empty string and insert the result into a temp table. In our system a Case can have multiple Debtors. The primary debtor will have an DEIsPrimary value of 1. CApKey is the key value of the case.
If I do this, using a single column I get the expected result:
(SELECT DEPhone FROM
(SELECT ROW_NUMBER() OVER (ORDER BY DEpKey ASC)
AS rownumber, DEPhone FROM Debtor d WHERE d.CApKey = 151490 AND d.DEIsPrimary <> 1)
AS foo WHERE rownumber = 1)
This returns a valid phone number. When I try to expand on this, using the concatenated names like so:
(SELECT DEFirstName + ' ' + DELastName FROM
(SELECT ROW_NUMBER() OVER (ORDER BY DEpKey ASC)
AS rownumber, DEFIrstName + ' ' + DELastName FROM Debtor d WHERE d.CApKey = 151490 AND d.DEIsPrimary <> 1)
AS foo WHERE rownumber = 1)
I get two errors: I'm told that DEFirstName and DELastName are invalid column names, and I'm also told that no column was specified for column 2 of foo. Is concatenation not possible in this context? I've tried aliasing the names with no luck. Here is almost what I think I need, but as you can see I haven't even gotten the COALESCE in yet. Here was my initial attempt:
UPDATE #temp SET OwnerNameTwo = (SELECT DEFirstName + ' ' + DELastName FROM
(SELECT ROW_NUMBER() OVER (ORDER BY DEpKey ASC)
AS rownumber, DEFirstName + ' ' + DELastName
FROM Debtor d WHERE d.CApKey = #temp.CApKey AND d.DEIsPrimary <> 1)
AS foo WHERE rownumber = 1)
Thank you in advance for any time spent helping me with this. I really appreciate any and all feeback!
答案 0 :(得分:0)
When you build a derived table you cannot access the columns of the underlying tables directly unless they appear in the list after SELECT
in the outermost query of the derived table.
So
SELECT a
FROM (SELECT a
FROM t) x;
works, while
SELECT b
FROM (SELECT a
FROM t) x;
doesn't work even if there is a column b
in t
.
But in fact this goes a bit further. You can select any of the column expressions from the outermost query as in
SELECT y
FROM (SELECT a + b y
FROM t) x;
But you need a name for each those columns given by expressions. Whilst some systems might automatically generate usable aliases for expressions some don't and even if they do, these aliases often aren't "nice" to read and write. So use explicit aliases.
What you cannot do here is to repeat the expression and hope that'll give you the respective value. I.e.
SELECT a + b
FROM (SELECT a + b
FROM t) x;
won't work.
But the last query is what you do.
So either move the concatenation to the outer query and just list the columns in the inner query
UPDATE #temp
SET ownernametwo = (SELECT defirstname + ' ' + delastname
FROM (SELECT row_number() OVER (ORDER BY depkey ASC) rownumber,
defirstname,
delastname
FROM debtor d
WHERE d.capkey = #temp.capkey
AND d.deisprimary <> 1) foo
WHERE rownumber = 1);
or keep the concatenation in the inner query alias it an us that alias in the outer query:
UPDATE #temp
SET ownernametwo = (SELECT fullname
FROM (SELECT row_number() OVER (ORDER BY depkey ASC) rownumber,
defirstname + ' ' + delastname fullname
FROM debtor d
WHERE d.capkey = #temp.capkey
AND d.deisprimary <> 1) foo
WHERE rownumber = 1);