sql select query IN Clause returns nothing - sql

Is it possible to get any value from the parameters passed inside IN clause where 1 value returns nothing.
Example:
select id, translation
from <table>
where id in (1,2,36)
and (locale_id='EN' )
If id 2 has no values in table, is it possible to return NULL in place of no values at all.
Currently it returns only 2 values.

try this:
with cte as (
select *
from (values (1),(2),(36) ) v(v)
)
select *
from cte
left join table1 t1 on t1.id=cte.v and (t1.locale_id='EN' )
you'll get at least on record per id
cte generates 3 records, each with one value v i prefer the syntax with cte over the following version (which should do the same)
select *
from (values (1),(2),(36)) v(v)
left join table1 t1 on t1.id=v.v and (t1.locale_id='EN' )
the left join well read yourself : http://www.w3schools.com/sql/sql_join_left.asp

Related

How to get all non matching rows from both tables in one query?

I have two tables with similar columns and I would like to know the difference between these tables. So if all values (column-wise) of the row exists in both table it is fine (I do not want to see this), while I want to see all rows that.
I have tried this:
select m.*, t.*
from test.test1 m
full outer join test.test2 t
on row(m) = row(t)
where m.date = '2022-11-01'
but I am getting all rows only from the first table. Note. I want only one query (no subqueries)
You need to add the null check for your key columns in the where statement:
select m.*, t.*
from test.test1 m
full outer join test.test2 t
on row(m) = row(t)
where m.KEY is null or t.KEY is null and m.date = '2022-11-01'
You can use the EXCEPT/EXCEPT ALL set operators to compare tables with the column layout (data-types and order of columns (if using SELECT *) must match).
SELECT 'IN TEST1 but not in TEST2' as SRC, EA.*
FROM (
SELECT *
FROM test.test1 m
where m.date='2022-11-01'
EXCEPT ALL
SELECT *
FROM test.test2
) EA
union all
SELECT 'IN TEST2 but not in TEST1' as SRC, EA.*
FROM (
SELECT *
FROM test.test2
EXCEPT ALL
SELECT *
FROM test.test1 m
where m.date='2022-11-01'
) EA

How to combine multiple SELECT statements into a single query & get a single result output

I have multiple SELECT queries which is ran against different tables.
The output of all the queries have the same number of rows (every query when ran individually will have the same number of rows). Is there a way I can combine the output of all these queries into a single result? (Keep out from first query and add the output of next query as a column to the output of the next query). I dont want to save these tables into database as I am just doing some validation testing.
Example:
SELECT AAA,BBB,CCC FROM Table1
SELECT Table2.DDD, Table1.AAA
FROM Table2
INNER JOIN Table1
ON Table1.AAA = Table2.AAA
I tried writing combining the query as
SELECT Table1.AAA,Table1.BBB,Table1.CCC,T1.DDD
FROM Table1,
(SELECT Table2.DDD, Table1.AAA
FROM Table2
INNER JOIN Table1
ON Table1.AAA = Table2.AAA)T1
I tried doing the above combined query, but instead of getting 11 rows as output (both queries above had result of 11 rows), I am getting 35 rows as output.
Hope the question made sense!
You'll need to specify a criteria to match each row the first query with which row of the second query.
If, for example, the column AAA is unique in both queries and you want to match rows with the same values you could do:
select a.*, b.*
from (
SELECT AAA,BBB,CCC FROM Table1
) a
full join join (
SELECT Table2.DDD, Table1.AAA
FROM Table2
INNER JOIN Table1
ON Table1.AAA = Table2.AAA
) b on b.aaa = a.aaa
If there aren't any clear matching rules, you can produce an artificial row number on each result set and use it to match rows. For example:
select
a.aaa, a.bbb, a.ccc,
b.ddd, b.aaa
from (
SELECT AAA, BBB, CCC,
row_number() over(order by aaa) as rn
FROM Table1
) a
full join join (
SELECT Table2.DDD, Table1.AAA,
row_number() over(order by table1.aaa, table2.ddd) as rn
FROM Table2
INNER JOIN Table1
ON Table1.AAA = Table2.AAA
) b on b.rn = a.rn
If you have several results and want to have all of them as additional columns you can simply use ",":
create table temp1 as select '1' as c1 from DUAL;
create table temp2 as select '2' as c2 from DUAL;
create table temp3 as select '3' as c3 from DUAL;
select a.c1, b.c2, c.c3 from temp1 a, (select c2 from temp2) b, (select c3 from temp3) c;
An alternative could also be that you want to have all the results as additional rows then you would use UNION ALL between the individual results.

Standard SQL: LEFT JOIN by two conditions using BETWEEN

I have the following query in BigQuery:
#Standard SQL
SELECT *
FROM `Table_1`
LEFT JOIN `Table_2` ON (timestamp BETWEEN TimeStampStart AND TimeStampEnd)
But I get the following Error:
Error: LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join.
If I use JOIN instead of LEFT JOIN, it works, but I want to keep all the rows from Table_1 (so also the ones which aren't matched to Table_2)
How to achieve this?
This is absolutely stupid... but the same query will work if you add a condition that matches a column from table1 with a column from table2:
WITH Table_1 AS (
SELECT CAST('2018-08-15' AS DATE) AS Timestamp, 'Foo' AS Foo
UNION ALL
SELECT CAST('2018-09-15' AS DATE), 'Foo'
), Table_2 AS (
SELECT CAST('2018-08-14' AS DATE) AS TimeStampStart, CAST('2018-08-16' AS DATE) AS TimeStampEnd, 'Foo' AS Bar
)
SELECT *
FROM Table_1
LEFT JOIN Table_2 ON Table_1.Foo = Table_2.Bar AND Table_1.Timestamp BETWEEN Table_2.TimeStampStart AND Table_2.TimeStampEnd
See if you have additional matching criteria that you can use (like another column that links table1 and table2 on equality).
A LEFT JOIN is always equivalent to the UNION of :
the INNER JOIN between the same two arguments on the same join predicate, and
the set of rows from the first argument for which no matching row is found (and properly extended with null values for all columns retained from the second argument)
That latter portion can be written as
SELECT T1.*, null as T2_C1, null as T2_C2, ...
FROM T1
WHERE NOT EXISTS (SELECT * FROM T2 WHERE )
So if you spell out the UNION you should be able to get there.
Interesting. This works for me in standard SQL:
select *
from (select 1 as x) a left join
(select 2 as a, 3 as b) b
on a.x between b.a and b.b
I suspect you are using legacy SQL. Such switch to standard SQL. (And drop the parentheses after the between.)
The problem is:
#(Standard SQL)#
This doesn't do anything. Use:
#StandardSQL
Hi as per the documentation, "(" has a special meaning, so please try without the brackets.
SELECT * FROM Table_1
LEFT JOIN Table_2 ON Table_1.timestamp >= Table_2.TimeStampStart AND Table_1.timestamp <= Table_2.TimeStampEnd
Documentation here

SQL Update Multiple Rows with Count from another Table

Suppose I have two tables. One table, tbl1, is "long" and non-aggregated. The structure is as follows:
Software_Name:
Word
PowerPoint
PowerPoint
Excel
Word
PowerPoint
In a second Table, tbl2, I want to summarize the data from the first table, namely the count of Software. The second Table will have a structure like:
Software_Name: Count:
Word 2
PowerPoint 3
Excel 1
I have tried:
update tbl2
set count =
(select count(software_name)
from tbl1
group by software_name
where tbl1.software_name = tbl2.software_name)
from tbl1
I get a result inserted into the proper column, but it is not the proper value. It is the sum of all values, in this case 5. I have included the where clause because in my tbl1 I have many more software_names than am interested in counting in tbl2.
UPDATE
I am using Teradata Aster for this project. I have been looking at the Aster documentation for the UPDATE command and came across this:
UPDATE [ ONLY ] table
SET column = expression [, ...]
[ FROM fromlist ]
[ WHERE condition | WHERE CURRENT OF cursor_name ];
In reading about the fromlist, I came across this bit of information:
Note that the target table must not appear in the fromlist unless you intend a
self-join (in which case it must appear with an alias in the fromlist).
You want a correlated subquery:
update tbl2
set count = (select count(*) from tbl1 where tbl1.software_name = tbl2.software_name);
Not sure what DBMS you're using but in SQL Server I would recommend a CROSS APPLY with example below...
update t2
set t2.[Count] = t1.[Count]
from t2
cross apply (
select count(*) AS [Count]
from t1
where t1.Software_name = t2.Software_name
) AS t1
You can read more about the APPLY operator here: https://www.mssqltips.com/sqlservertip/1958/sql-server-cross-apply-and-outer-apply/
You can try using the CTE as below:
DECLARE #TABLE1 AS TABLE (Software_Name VARCHAR(100))
INSERT INTO #TABLE1
SELECT 'Word'
UNION ALL
SELECT 'PowerPoint'
UNION ALL
SELECT 'PowerPoint'
UNION ALL
SELECT 'Excel'
UNION ALL
SELECT 'Word'
UNION ALL
SELECT 'PowerPoint'
DECLARE #TABLE2 AS TABLE (Software_Name VARCHAR(100),Cnt INT)
INSERT INTO #TABLE2 (Software_Name)
SELECT DISTINCT Software_Name FROM #TABLE1
;WITH CTE AS
(
SELECT
COUNT(T1.Software_Name) AS Cnt
,T1.Software_Name
FROM #TABLE2 T2
INNER JOIN #TABLE1 T1 ON T1.Software_Name = T2.Software_Name
GROUP BY
T1.Software_Name
)
UPDATE T2
SET
T2.Cnt = C.Cnt
FROM #TABLE2 T2
INNER JOIN CTE C ON C.Software_Name = T2.Software_Name
SELECT * FROM #TABLE2
NOTE: I am assuming you are using SQL Server. Also i am posting it as an answer as i dont have desired reputation to comment.
hope it helps!

getting distinct value with all column sqlserver

select
distinct TagName as new, *,(REPLACE(TagName,' ','-')) as SeoProduct_Name
from
dbo.tbl_Image_Master
inner join
dbo.tbl_size
on tbl_size.Size_Id=tbl_Image_Master.Size_Id
inner join
tbl_category
on tbl_category.Cat_Id = tbl_Image_Master.Cat_Id
I want to select distinct tag name with all column
SELECT * FROM TBL WHERE TAGNAME IN (
SELECT DISTINCT TAGNAME FROM TBL)
OR
SELECT * FROM (
SELECT *,ROW_NUMBER() OVER (PARTITION BY TAGNAME ORDER BY (SELECT 1)) AS ROWNUM FROM TBL WHERE TAGNAME)
WHERE ROWNUM =1
Hope it solves the Purpose !!!
If you want to get all columns from a table in a query you can use this syntax :
TableName.*
Example :
Select Table1.Col1, Table1.* from Table1;
I would post what your query becomes, but I am not sure what table you want all columns from.
In the distinct query you cannot select all the columns you need because if you do so you are going to get multiple values that you don't need.
So what you can do is to use you query inside another query, as for example
SELECT TagName AS new, *,(REPLACE(TagName,' ','-')) AS SeoProduct_Name,
<other_colums_you_need>
FROM <table>
WHERE ItemID IN (
SELECT DISTINCT TagName <replaceWithSomeID>
FROM dbo.tbl_Image_Master
INNER JOIN dbo.tbl_size
ON tbl_size.Size_Id=tbl_Image_Master.Size_Id
INNER JOIN tbl_category
ON tbl_category.Cat_Id = tbl_Image_Master.Cat_Id
)
Remember that the values that you require (rows) need to have an unique identifier or ID column, so make sure to return in the subquery that unique ID of the values you need. So you are only going to get the info you require.