SQL 'belong to' logic - sql

So, I have been trying to write a query in SQL but facing an issue. I am trying to write a 'belongs to' kind of condition. What I want to do is if the values being fetched belongs to a column in another table then populate one thing otherwise populate null.
for ex.
NAME table
ID NAMES
1 A
2 B
3 C
4 D
5 E
XYZ table
ID
2
4
5
I wrote the query something like this
(CASE WHEN NAME.ID IN (SELECT ID FROM XYZ) THEN NAME.NAMES ELSE NULL END ) AS 'ABC'
This query does run but it has been running for 14 hours (OBVIOUSLY FOR A VERY HUGE AMOUNT OF DATA) and still there is no result. Is there some flaw in this logic or is there some better way it could be done?
I expect a result like this:
ABC
NULL
B
NULL
D
E

You just need a plain left join here:
SELECT
CASE WHEN t2.ID IS NOT NULL THEN t1.NAMES END AS ABC
FROM NAME t1
LEFT JOIN XYZ t2
ON t1.ID = t2.ID;
Demo
Note that a CASE expressions else condition, if not explicitly specified, defaults to NULL. This behavior works here because you want to render NULL if a given record in the NAME table does not match to any record in the XYZ table.

The problem isn't your logic. It is simply how the code is optimized. The subquery is probably being run for each row in the outer query.
I would recommend switching to exists:
(case when exists (select 1 from xyz where xyz.id = name.id) then name.names
end) as abc
This maintains the semantics of your original query. In particular, there is no danger that duplicates in xyz would return multiple rows (as would happen with a left join).
For performance for this -- or for the left join -- you want an index on xyz(id).

Related

Case Statement for Joined Table

I have two tables:
Account ID | A | B
-------------------
1 | x | y
2 | c | f
3 |...|...
the first table is a general account list. The second table is a list of documents on hand for each acct:
Account ID | Doctype
---------------------
1 | chrgoff
2 | dtpmnt
2 | chrgoff
3 | lstpmt
3 | suit
For the report I'm creating, I need to create a column in the first table which stores the value of a flag, where 'Y' indicates that the second table contains the docType 'chrgoff' for a given account number.
I tried doing this with the following case statement, but the query won't execute at all:
'chgoff' =
CASE
WHEN EXISTS(SELECT docType FROM table2 WHERE docType='chrgoff' and AccountID=table1.accountID)
THEN 'Y'
ELSE 'N'
END
I'm very new to T-SQL programming, so I would appreciate any help I could get! Let me know if I need to clarify anything. Thanks!
You code looks okay, but I would suggest:
(CASE WHEN EXISTS (SELECT docType FROM table2 t2 WHERE t2.docType = 'chrgoff' and t2.AccountID = table1.accountID)
THEN 'Y'
ELSE 'N'
END) as chgoff
The main differences are:
No single quotes on the column name. Only use single quotes for string and date constants.
Qualify the column references in the subquery. Don't depend on SQL's scoping rules. Be explicit.
As for as versus =. I prefer the former because it is standard SQL; = only assigns column aliases in SQL Server and related databases.
Alternate way - You can flag a record by joining both the tables with left outer join. I believe it would be faster approach than EXIST with subquery.
SQL -
select t1.*,
case when t2.account_id is not null then 'Y' else 'N' end as chgoff
from table1 t1
left join table2 t2 on t1.account_id = t2.account_id and t2.doctype = 'chrgoff'

Duplicate rows in left join

I have 2 tables. There are about 100000 of null in one column, other values are integer, total values are about 200000. Another table has only the integer value. When I use the left join on this column, it gave me a lot of duplicates rows. Is it ok to use left join here?
Table 1:
Column 1
2
3
5
null
null
Table 2:
Column 1
1
2
3
so on
Your example is really odd. Why would anyone have null values in an ID field? But anyway.
If you need fields from table 2 in the resultset as you say above then you must use an INNER JOIN not a LEFT JOIN
Something like:
SELECT DISTINCT a.id, a.name, b.someOtherField
FROM Table1 a
INNER JOIN Table2 b ON a.id = b.id
Please note: Since only the ID field of table 1 has null values there will be no records selected from table 1 with id IS NULL because they have no equivalent in table 2. Adding the DISTINCT keyword helps in case this query would still produce duplicates.

SQL STATEMENT QUERY

I have table1Name with data populated and table2 with no data populated.
select * from [database1Name].dbo.table1Name
join [database1Name].dbo.table2Name
on [database1Name].dbo.table1Name.fieldName like value;
After running the above sql statement it joins the tables but does not show any populated data from the table 'table1Name'.
Why does this happen?
Using JOIN which is an INNER JOIN means that it will get you only data where the condition matches. So if the second table has not data, then the condition is never met, so you get no data in return.
In your case you need a LEFT JOIN. This will get all the rows from the left table (table1Name in your case) and the corresponding values from the right table when the condition is met.
SELECT *
FROM [database1Name].dbo.table1Name
LEFT JOIN [database1Name].dbo.table2Name
ON [database1Name].dbo.table1Name.fieldName like [database1Name].dbo.table2Name.fieldName;
Just to mention that using joins mean that you might get multiple times a single row from a specific table. For instance since you have a LIKE condition, if fieldName of Table 1 matches fieldName in 2 rows from Table 2 then you will get two rows containing the same row from Table 1 and the two rows from Table 2:
Example:
Table1
FieldName
1
2
Table2
FieldName OtherField
1 1
1 2
Result of LEFT JOIN
T1FieldName T2FieldName T2OtherField
1 1 1
1 1 2
2 NULL NULL

SQL Join query to return matching and non-matching record

I am working on a SQL Syntax to write a Join query.
I couldnt get the expected output, i request expert to help me.
Table: Table1
ScriptNumber Date Filled RefillsLeft
100 01/02/2014 1
200 01/03/2014 0
300 01/22/2014 3
Table : Table 2
ScriptNumber Date Filled RefillsLeft
100 02/02/2014 0
Expected output
ScriptNumber Date Filled RefillsLeft
100 02/02/2014 0
300 null null
SQL Statement
SELECT Table_2.ScriptNumber
,Table_2.DateFilled
,Table_2.RefillsLeft
FROM Table_1
LEFT JOIN Table_2
ON Table_1.ScriptNumber = Table_2.ScriptNumber
Your problem is coming from including columns in SELECT statement from table_2 that do not have values for rows that exists in table_1. You need to change SELECT Table_2.ScriptNumber to SELECT Table_1.ScriptNumber
As future reference make sure you always select all relevant columns from LEFT tables and only columns you need from RIGHT table. Otherwise you end up with less NULL rows instead of having data that is present in LEFT table.
A left join could be useful here to get the records you want in Table_1 and any relevant details that may exist in Table_2
select Table_1.ScriptNumber
, Table_2.DateFilled
, Table_2.RefillsLeft
from Table_1
left join Table_2 on Table_1.ScriptNumber = Table_2.ScriptNumber
where Table_1.RefillsLeft > 0
Such a description is helpful in your questions, too.

SQL - Join two query in same query with two rows

i have one query that i need include the status in another row, i think that it's easy but i'm not remember it..
status
A
B
C
D
job
1
2
3
i want a output like:
job status
1 A
1 B
1 C
1 D
2 A
2 B
2 C
2 D
...
Can anyone help?
that is called CROSS JOIN
SELECT *
FROM status CROSS JOIN job;
I'm just guessing your table layout here because you did not give it in your question.
SELECT t1.job, t2.status
FROM t1 INNER JOIN t2 ON t1.something = t2.something
Note that if you had given the table structure something, t1 and t2 would actually be the real names.
If there is no particular key and you just want to match every value of t1.job to every value of t2.status then this will do the job:
SELECT t1.job, t2.status
FROM t1, t2
You might want to read a little bit about JOINs in SQL, here's a good resource:
http://www.w3schools.com/sql/sql_join.asp
As per your case, you can simply do:
SELECT * FROM job, status
Assuming that those are table names and these are the only columns in there.
EDIT:
Link with explanation on how CROSS JOIN works as well:
http://www.w3resource.com/sql/joins/cross-join.php