Variable not getting set by select - sql

I have an issue where a variable is not getting set by a select statement.
The select joins a table variable #contracts (which is used to control a loop) and then joins to the real contract and contract line tables.
my select is:
select top 1
#contract_id = c.contract_id
, #account = ch.account
, #service = cl.service
, #model = cl.model
, #serial = cl.serial
, #contract = ch.contract
from
#contracts c
inner join contractline cl on c.contract_id = cl.contract_id
inner join contractheader ch on cl.contract = ch.contract
where
cl.contract_id = #contract_id
But when I do a select #contract_id say i get a NULL back, as do all my variables.
I have done a simple select * from #contracts c inner join contractline cl on c.contract_id = cl.contract_id inner join contractheader ch on cl.contract = ch.contract and this returns exactly 1 line with the values in all the correct places, no nulls in the selected values.
What have I done wrong?

Looks like your WHERE clause could be stopping the row from returning. You mentioned you've tested the same SELECT without setting variable, but the code you listed doesn't include this WHERE - so its not the same.
Test your SELECT with the WHERE in place, with dummy values (likely NULL) and review. It simply sounds like its not returning a result.

You are setting #contract_id in the select statement but then also using it in the where clause. I would have thought that #contract_id will be null?

Related

SQL Join / Union

I have two statements that I want to merge into one output.
Statement One:
select name from auxiliary_variable_inquiry
where inquiry_idbr_code = '063'
Returns the following list of names:
Name
------------
Affiliates
NetBookValue
Parents
Worldbase
Statement Two:
select name, value from auxiliary_variable_value
where inquiry_idbr_code = '063'
and ru_ref = 20120000008
and period = 200912
Returns the following:
Name Value
-------------------
Affiliates 112
NetBookValue 225.700
I would like to have an output like this:
Name Value
-------------------
Affiliates 112
NetBookValue 225.700
Parents 0
Worldbase 0
So basically, if the second query only returns 2 names and values, I'd still like to display the complete set of names from the first query, with no values. If all four values were returned by both queries, then all four would be displayed.
Sorry I must add, im using Ingres SQL so im unable to use the ISNULL function.
You can do a left join. This ensures that all records from the first table will stay included. Where value is null, no child record was found, and we use coalesce to display 0 in these cases.
select i.name, COALESCE(v.Value,0) from auxiliary_variable_inquiry i
left join auxiliary_variable_value v
on v.inquiry_idbr_code = i.inquiry_idbr_code
and v.ru_ref = 20120000008
and v.period = 200912
where i.inquiry_idbr_code = '063'
I'd recommend a self-JOIN using the LEFT OUTER JOIN syntax. Include your 'extra' conditions from the second query in the JOIN condition, while the first conditions stay in the WHERE, like this:
select a.name, CASE WHEN b.Value IS NULL THEN 0 ELSE b.Value END AS Value
from
auxiliary_variable_inquiry a
LEFT JOIN
auxiliary_variable_inquiry b ON
a.name = b.name and -- replace this with your real ID-based JOIN
a.inquiry_idbr_code = b.inquiry_idbr_code AND
b.ru_ref = 20120000008 AND
b.period = 200912
where a.inquiry_idbr_code = '063'
if i got right, you should use something like:
SELECT i.NAME,
v.NAME,
v.value
FROM auxiliary_variable_inquiry i
LEFT JOIN auxiliary_variable_value v
ON i.inquiry_idbr_code = v.inquiry_idbr_code
WHERE v.ru_ref = 20120000008
AND v.period = 200912

SQL update with count gets only nulls

I am using SQL Server 2008 R2 and SSRS 2008 to generate the report. I am trying to update a table to get a count of the results from another table.
UPDATE r
SET r.Race = d2.Race,
r.RaceNum = d2.count
FROM #results r
INNER JOIN
(SELECT d.Race,
COUNT(d.race) AS 'count'
FROM #Demographic d
GROUP BY d.Race)d2 ON r.Race = d2.Race
An insert works perfectly but I am inserting several times into the results table to create a demographics report. This is creating a lot Null data at the table of the results. If anyone has an idea of what I am going wrong the help would be appreciated.
Not certain, but first guess is that count is a reserved word... change it to something else such as...
update r
set r.Race = d2.Race, r.RaceNum = d2.cnt
from #results r
inner join
(select d.Race, COUNT(d.race) as 'cnt' from #Demographic d group by d.Race)d2
on r.Race = d2.Race
or alternatively try delimiting the column identifier as [count] or if you have quoted identifiers on "count"
Your query is:
update r
set r.Race = d2.Race, /*<---------*/
r.RaceNum = d2.count
from #results r inner join
(select d.Race, COUNT(d.race) as 'count'
from #Demographic d
group by d.Race
) d2
on r.Race = d2.Race /*<-------- */
The two marked lines stand out. You are joining on values using =, then you are setting one equal to the other. This may not be the problem, but it is suspicious. If you are joining on them, why are you setting them equal? My suspicion is that the join is failing, because nothing matches it.
You don't need to update the race column, since that's the equality portion of your join.
As written, any race not in #demographic would have its racenum set to null. If you want 0 for those try:
UDPATE
r
SET
r.RaceNum = ISNULL(d2.ct, 0)
FROM #results r
LEFT JOIN
(
SELECT
d.Race
, COUNT(d.race) as ct
FROM
#Demographic d
GROUP BY
d.Race
) d2
ON
r.Race = d2.Race

Doing an Update Ignore in SQL Server 2005

I have a table where I wish to update some of the rows. All the fields are not null. I'm doing a sub-query, and I wish to update the table with the non-Null results.
See Below for my final answer:
In MySQL, I solve this problem by doing an UPDATE IGNORE. How do I make this work in SQL Server 2005? The sub-query uses a four-table Join to find the data to insert if it exists. The Update is being run against a table that could have 90,000+ records, so I need a solution that uses SQL, rather than having the Java program that's querying the database retrieve the results and then update those fields where we've got non-Null values.
Update: My query:
UPDATE #SearchResults SET geneSymbol = (
SELECT TOP 1 symbol.name FROM
GeneSymbol AS symbol JOIN GeneConnector AS geneJoin
ON symbol.id = geneJoin.geneSymbolID
JOIN Result AS sSeq ON geneJoin.sSeqID = sSeq.id
JOIN IndelConnector AS joiner ON joiner.sSeqID = sSeq.id
WHERE joiner.indelID = #SearchResults.id ORDER BY symbol.id ASC)
WHERE isSNV = 0
If I add "AND symbol.name IS NOT NULL" to either WHERE I get a SQL error. If I run it as is I get "adding null to a non-null column" errors. :-(
Thank you all, I ended up finding this:
UPDATE #SearchResults SET geneSymbol =
ISNULL ((SELECT TOP 1 symbol.name FROM
GeneSymbol AS symbol JOIN GeneConnector AS geneJoin
ON symbol.id = geneJoin.geneSymbolID
JOIN Result AS sSeq ON geneJoin.sSeqID = sSeq.id
JOIN IndelConnector AS joiner ON joiner.sSeqID = sSeq.id
WHERE joiner.indelID = #SearchResults.id ORDER BY symbol.id ASC), ' ')
WHERE isSNV = 0
While it would be better not to do anything in the null case (so I'm going to try to understand the other answers, and see if they're faster) setting the null cases to a blank answer also works, and that's what this does.
Note: Wrapping the ISNULL (...) with () leads to really obscure (and wrong) errors.
with UpdatedGenesDS (
select joiner.indelID, name, row_number() over (order by symbol.id asc) seq
from
GeneSymbol AS symbol JOIN GeneConnector AS geneJoin
ON symbol.id = geneJoin.geneSymbolID
JOIN Result AS sSeq ON geneJoin.sSeqID = sSeq.id
JOIN IndelConnector AS joiner ON joiner.sSeqID = sSeq.id
WHERE name is not null ORDER BY symbol.id ASC
)
update Genes
set geneSymbol = upd.name
from #SearchResults a
inner join UpdateGenesDs upd on a.id = b.intelID
where upd.seq =1 and isSNV = 0
this handles the null completely as all are filtered out by the where predicate (can also be filtered by join predicate if You wish. Is it what You are looking for?
Here's another option, where only those rows in #SearchResults that are succesfully joined will be udpated. If there are no null values in the underlying data, then the inner joins will pull in no null values, and you won't have to worry about filtering them out.
UPDATE #SearchResults
set geneSymbol = symbol.name
from #SearchResults sr
inner join IndelConnector AS joiner
on joiner.indelID = sr.id
inner join Result AS sSeq
on sSeq.id = joiner.sSeqID
inner join GeneConnector AS geneJoin
on geneJoin.sSeqID = sSeq.id
-- Get "lowest" (i.e. first if listed alphabetically) value of name for each id
inner join (select id, min(name) name
from GeneSymbol
group by id) symbol
on symbol.id = geneJoin.geneSymbolID
where isSNV = 0 -- Which table is this value from?
(There might be some syntax problems, without tables I can't debug it)

How to create a function that returns the first value of sorted list in SQL?

I'm writing a SQL function that returns the first value of a sorted list, but I really don't know how to start? The function has only one parameter which is the listing number ( VRI.Listing_Number )
Using select statement, I have:
SELECT TOP 1
--VRI.Listing_RID, VRI.Listing_Number, VRI.Listing_Price, CH.Old_Price, CH.Date_Time_Changed
CH.Old_Price
FROM dbo.View_Report_Information_Tables VRI WITH (NOLOCK)
INNER JOIN dbo.MLS_Change_History CH WITH (NOLOCK) ON
VRI.Listing_RID = CH.Listing_RID
INNER JOIN dbo.MLS_Change_History_Type CHT WITH (NOLOCK) ON
CH.Transaction_RID = CHT.Transaction_RID
WHERE CHT.Change_Type_Display = 3 AND
VRI.Listing_RID = CH.LISTING_RID
ORDER BY CH.Transaction_RID DESC
This sql query returns the last price changes from a list of prices.
I'm really new to sql, so I even don't understand quite well the syntax. For example, I looked up the CH.Old_Price, and I saw it TYPE_NAME is numeric, but it also has length and precision, scale.... What should my return value for this function?
Any idea?
Thanks,
CREATE FUNCTION dbo.FirstPriceChange(#Listing_Number int)
RETURNS MONEY
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
RETURN (
SELECT TOP 1
CH.Old_Price
FROM dbo.View_Report_Information_Tables VRI WITH (NOLOCK)
INNER JOIN dbo.MLS_Change_History CH WITH (NOLOCK) ON
VRI.Listing_RID = CH.Listing_RID
INNER JOIN dbo.MLS_Change_History_Type CHT WITH (NOLOCK) ON
CH.Transaction_RID = CHT.Transaction_RID
WHERE CHT.Change_Type_Display = 3 AND
VRI.Listing_RID = CH.LISTING_RID AND
VRI.Listing_Number = #Listing_Number
ORDER BY CH.Transaction_RID DESC
)
END
GO
Sample usage:
SELECT
VRI.Listing_RID, VRI.col1, VRI.Col2,
dbo.FirstPriceChange(VRI.Listing_Number) AS FirstPriceChange
FROM dbo.View_Report_Information_Tables VRI
Notes:
RETURNS MONEY it returns a money type
WITH RETURNS NULL ON NULL INPUT if the input is null, just return null
The returns is a single value, which is from the subquery, with the VRI.Listing_Number filter added
assuming the select statement you posted returns the correct data, the syntax of the function is rather simple:
CREATE FUNCTION <Inline_Function_Name, sysname, FunctionName>
(
-- Add the parameters for the function here
#Listing_Number int,
)
RETURNS TABLE
AS
RETURN
(
-- Add the SELECT statement with parameter references here
)
you can also get this by right-clicking Functions in SSMS -> Object Explorer -> -> Programmability and choosing the right type of function. My sample above assumes that this returns an entire row of data (which seems to be the case). I also assumed that VRI.Listing_Number is an int.
SELECT TOP 1 FROM (
SELECT *
FROM dbo.View_Report_Information_Tables VRI WITH (NOLOCK)
INNER JOIN dbo.MLS_Change_History CH WITH (NOLOCK) ON
VRI.Listing_RID = CH.Listing_RID
INNER JOIN dbo.MLS_Change_History_Type CHT WITH (NOLOCK) ON
CH.Transaction_RID = CHT.Transaction_RID
WHERE CHT.Change_Type_Display = 3 AND
VRI.Listing_RID = CH.LISTING_RID
ORDER BY CH.Transaction_RID DESC
) AS `aaa`

Can you rename a table using the keyword 'AS' and a select statement?

This is probably a stupid question to most of you but I was wondering whether you can rename a column using the 'AS' keyword and a select statement?
Here is my SQL:
Select Main.EmpId
, Associate_List.costCenter, Assignments.Area
, Main.Assignments_1 AS (
Select Assignment_Name
from Assignments
where Assignment_Number = 1
and Assignments.Area = '#Someparemeter'
)
from associate_list
, main
, APU_CC
, Assignments
where Main.Empid = Associate_List.Empid
and substring(Associate_List.CostCenter,1,4) = APU_CC.CostCentre
The only part of SQL I'm wondering about is:
Main.Assignments_1 AS (
Select Assignment_Name
from Assignments
where Assignment_Number = 1
and Assignments.Area = '#Someparemeter'
)
Is this possible or am I talking jibberish or is this just a stupid thing to do?
Many Thanks
The part after as is not a value but a variable name; the SQL database will use it to reference the value of the result set so you can compare/sort/filter them. Therefore this is not possible.
If you must do this, you must read the documentation of your database how to build dynamic queries. But I suggest against it because it will cause strange errors that will be very hard to debug.
I'm not quite sure what you are driving at.
If there is a column in the Main table called Assignments_1, you can rename it in your query (to give a different header at the top of the output or for some other reason) like this...
SELECT MAIN.ASSIGNMENT_1 AS MY_NEW_NAME
FROM etc.
If you want a derived table in your query you name it like this...
SELECT MAIN.ASSIGNMENT_1,
SELECT *
FROM (SELECT THIS, THAT, THE_OTHER
FROM SOME_TABLE) AS DERIVED_TABLE
FROM etc.
If you didn't want either of those things, please clarify and we'll try to help.
In SQL Server, you can assign an alias to a column with AS like so:
...
ColumnName AS ColumnAlias,
...
And you can do it for a "sub-select" like you have in your example. (I wouldn't write the query quite like that--I'd run the subquery first and then plop the result into the second query like so:
DECLARE #Assignment_Name varca(100) -- or however long
SELECT #Assignment_Name = Assignment_Name
from Assignments
where Assignment_Number = 1
and Assignments.Area = #Someparemeter
SELECT
...
#Assignment_Name = Assignment_Name,
...
But you can do this:
Select m.EmpId, l.costCenter,
(Select Area From Assignments a
Where Assignment_Number = 1
And Area = '#Someparemeter') As Area,
(Select Assignment_Name From Assignments a
Where Assignment_Number = 1
And Area = '#Someparemeter') As Assignments_1
From associate_list l
Join main m On m.Empid = l.Empid
Join APU_CC c On c.CostCentre = substring(l.CostCenter,1,4)
or this:
Select m.EmpId, l.costCenter, Asgn.Area,
Asgn.Assignment_Name as Assignments_1
From associate_list l
Join main m On m.Empid = l.Empid
Join APU_CC c On c.CostCentre = substring(l.CostCenter,1,4)
Cross Join (Select Assignment_Name From Assignments a
Where Assignment_Number = 1
And Area = '#Someparemeter') as Asgn