SELECT refering value to sub query - sql

I am trying to get a random id value from my table. The condition is that the selected value must not exist for the same id and different language (language is lang field)
I do this:
SELECT id_v as p,cont FROM value_phrase WHERE lang=1 AND
NULL IN (SELECT cont FROM value_phrase WHERE id_v=p AND lang=2)
ORDER BY RAND() LIMIT 0,1
... but I do not get any results (It must be an error in my query, because there are many rows satisfying the desired condition.) How should I fix it?
-- SOLVED --
the solution is to use NOT EXISTS instead of NULL IN, and use table aliases to refer the first id_v into the sub query. This way (thanks to Mark Byers):
SELECT first.id_v, first.cont
FROM value_phrase AS
FIRST WHERE lang =1
AND NOT
EXISTS (
SELECT cont
FROM value_phrase
WHERE id_v = first.id_v
AND lang =2
)
ORDER BY RAND( )
LIMIT 0 , 1

If you want to check if a value does not exist, use NOT EXISTS.
AND NOT EXISTS (SELECT ... )

Your condition NULL IN (...) will never return anything, because a comparison with NULL always returns NULL and that is treated as "false" in a query condition.

Related

Displaying an alternative result when derrived table is empty

I have this sql code where I try to display an alternative value as a result whenever the table is empty or the the single column of the top row when it is not
select top 1 case when count(*)!=0 then derrivedTable.primarykey
else 0 end endCase
from
(
select top 1 m.primarykey
from mytable m
where 0=1
)derrivedTable
The problem is that when I run this, I get the error message "column 'derrivedTable.primarykey' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."
But when I put 'derrivedTable.primarykey' in the group by clause, I just get an empty table.
Does anyone hve a solution?
thanks in advance
You can use aggregation:
select coalesce(max(m.primarykey), 0)
from mytable m;
An aggregation query with no group by always returns exactly one row. If the table is empty (or all rows are filtered out), then the aggregation functions -- except for COUNT() -- return NULL -- which can be transformed to a value using COALESCE().
Such a construct makes me worry. If you are using this to set the primary key on an insert, then you should learn about identity columns or sequences. The database will do the work for you.
Can you try this below script-
SELECT
CASE
WHEN COUNT(*) = 1 THEN derrivedTable.primarykey
ELSE 0
END endCase
FROM
(
SELECT TOP 1 m.primarykey
FROM mytable m
WHERE 0 = 1
) derrivedTable
derrivedTable.primarykey;

How to select specific row if X, multiple rows if Y

I got a table Table(id,name), but lets just work with id here
id
--
A
B
C
D
all
What I want is to select all rows (A,B,C D...) except 'all' if the input is all, otherwise only the specific value ( e.g.: A if the input is A ).
Do you guys have some tasty-juicy solution for this one? Thanks!
Let's say you have a parameter #Id in your query. Then you can formulate your WHERE clause based on #Id's value:
SELECT *
FROM MyTable t
WHERE i.Id <> 'all' AND (#Id='all' OR #Id=t.Id)
i.Id <> 'all' part ensures that 'all' row is never returned, regardless of the setting of #Id. The rest is your condition translated to SQL (i.e. either the query has 'all', or the query matches a single Id).
This looks like the wrong usage of a relational table as the "id" column should contain only ids...
I suggest removing the "all" row and instead write a stored procedure to decide whether to select all rows or just one.
Anyway, for your example:
SELECT * FROM your_table WHERE (id = #ID OR #ID = 'all') AND id <> 'all'

merge condition is not working in sql server

I have two tables one is (providerLoc) and another one is (tmpProviderLoc) I need to take three columns combination from tmpProviderLoc and need to check the records exist in ProviderLoc
Case 1 : If record exist in providerLoc i need to update another column(Npi) in providerLoc based on column (npi) in tmpProviderLoc
case 2 : if not exist i need to insert the values in providerLoc
for that I have written below query:
MERGE INTO [dbo].[ProviderLoc] AS PL
USING
(
select *
from (
select *,
row_number() over (partition by [Location_ID],[PProviderTaxID]
,[POBOXZIP] order by [Location_ID],[PProviderTaxID],[POBOXZIP]) as row_number
from [dbo].[TmpProviderLoc]
) as rows
where row_number = 1
) AS TPL
ON TPL.[Location_ID] = PL.[ecProviderID]
AND TPL.[PProviderTaxID] = PL.[TaxID]
AND TPL.[NPI] = PL.[NPI]
AND TPL.[POBOXZIP] = PL.[POBOXZIP]
WHEN MATCHED THEN
UPDATE SET PL.[NPI] = CASE
WHEN TPL.[NPI] = NULL THEN PL.[NPI]
ELSE TPL.[NPI]
END
WHEN NOT MATCHED THEN
INSERT (EcProviderID,TaxID,NPI,POBOXZIP,ProviderLocationStatusID,CreatedON)
VALUES (TPL.[Location_ID],TPL.[PProviderTaxID],TPL.[NPI]
,TPL.[POBOXZIP],1,GETDATE());
But I am failing in updating the NPI value -- if npi value is new in tmpProviderLoc it is not updating in ProviderLoc..
Could any one please look into this issue..
or any other way to go through this kind of checking
The equal symbol in this is incorrect: WHEN TPL.[NPI] = NULL THEN PL.[NPI]
Use IS NULL
WHEN TPL.[NPI] IS NULL THEN PL.[NPI]
NULLs are special. They are "indeterminate" so they cannot be equal or unequal to anything purely because they just cannot have any value "determined". NULLs are the absence of value and equal/unequal does not apply.
To discover if NULL exists use IS NULL - or - IS NOT NULL to discover if there is a non-null value.

Selecting from table to insert into another, getting a type error

I have the following query which inserts data into one table after selecting it from another.
The problem is that the data types do not match for one of the columns. I have simplified the query below.
INSERT INTO tbl.LogTable (
[SelPartNo], -- This does not match, see below
)
SELECT TOP 1
IF([SelPartNo] = 'False', NULL, [SelPartNo],
FROM tbl.MyTable
WHERE ID = '20358'
ORDER BY CreateDate DESC
The first SelPartNo is an int and the second is a VarChar. In most instances the SelPartNo for the second one (tbl.MyTable) is NULL or an integer, which I don't think will cause a problem. But in some cases the value is "False", which needs to return NULL.
I have tried an IF statement but I am doing something wrong because it's giving a syntax error and I am unsure if this is the correct approach.
Your code is syntactically incorect...
Try it with
NULLIF([SelPartNo],'False')
This function returns NULL if the two expressions are equal.
Details: https://msdn.microsoft.com/en-us/library/ms177562.aspx
I don't think IF is a function, at least not one which you can use in a SELECT statement. But CASE WHEN ... END is your friend:
INSERT INTO tbl.LogTable (
[SelPartNo]
)
SELECT TOP 1
CASE WHEN [SelPartNo] = 'False' THEN NULL ELSE [SelPartNo] END
FROM tbl.MyTable
WHERE ID = '20358'
ORDER BY CreateDate DESC

Is a subquery, which is returning no row, equal to NULL?

In SQL Server, if my SELECT statement in a subquery returns no row, is then the result of the subquery equal to NULL? I made some research, but I am not sure about it.
Example:
IF (SELECT TOP 1 CLMN1 FROM SOMETABLE) IS NOT NULL THEN
....
I am asking to understand the behaviour of the if-statement above.
Looks like the answer is yes:
DECLARE #Test TABLE (Id INT)
INSERT INTO #Test VALUES (1)
SELECT * FROM #Test WHERE Id = 2
SELECT CASE WHEN (SELECT * FROM #Test WHERE Id = 2) IS NULL THEN 1 ELSE 0 END
EDIT: after you updated your question I think I should add that instead of checking if there are rows with IS NULL you should use the following that can be better optimised by the server:
IF EXISTS(SELECT * FROM #Test WHERE Id = 2)
BEGIN
-- Whatever
END
NULL means no value, for example that the "box" for a certain column in a certain row is empty. NO ROW means that there are no rows.
No, NULL is a column value that indicates that the value of that column for a given row has no valid value. There would have to be a row returned by your query for that row to contain NULL column values.
A query that returns no rows just means that no rows matched the predicate you used in the query and therefore no data was returned at all.
Edit: After the question was edited, my answer doesn't address the specific case called out in the question. Juan's answer above does.