Finding Specific Rows in SQL which must Includes Value From ColumnB - sql

I have a table similar to below table. I want to select all ColumnA Values which has the Value "X" for ColumnB but also other possible ColumnB values.
ColumnA
ColumnB
One
X
One
Y
Two
Y
Two
Z
Three
X
Three
Z
So basically the query should result like this. Can you help me to achieve this?
ColumnA
ColumnB
One
X
One
Y
Three
X
Three
Z

One solution: once you know what Table1 values you want you can select them. So resolve that in a subquery. We'll alias the original table as X and the subquery as Y:
select X.*
from Table1 X
inner join
(
select
ColumnA
from
Table1
Where
ColumnB = 'X'
) Y
on X.ColumnA = Y.ColumnA

you could use min() over a window:
select columnA, columnB
from (
select *, min(columnb) over(partition by columna) mb
from t
)t
where mb = 'X';

I believe a subquery would be the simplest way.
Step 1 - find all the columnA values where columnB = 'x'
SELECT DISTINCT ColumnA
FROM table_name
WHERE ColumnB = 'x'
step 2 - select all the records where the value in ColumnA is in this list
SELECT *
FROM table_name
WHERE ColumnA in (SELECT DISTINCT ColumnA
FROM table_name
WHERE ColumnB = 'x')

Related

SQL: Add a SUM(ColumnA) AS ColumnB to a query returning ColumnA

I have a query that returns a number of columns, including ColumnA (which is numerical).
I want to add an additional column to the end of the query that returns the sum of ColumnA
ColumnA
ColumnB
10
37
20
37
5
37
2
37
SELECT
ColumnA,
SUM(ColumnA) AS ColumnB
FROM
Table
The code above doesn't work, but I'm not sure how to create something that will.
I think you need this query:
SELECT ColumnA, (SELECT SUM(ColumnA) FROM table) as ColumnB
FROM table
Something like
SELECT
ColumnA,
ColumnASum
FROM Table
LEFT JOIN (SELECT SUM(columnA) ColumnASum FROM Table)
ON TRUE;
Should work
You could create a variable of the SUM() first.
DECLARE #ColumnB int
SET #ColumnB = (SELECT SUM(ColumnA) FROM Table)
SELECT ColumnA, #ColumnB
FROM Table
This should give you what you need.
I would use CROSS APPLY.
SELECT Table.ColumnA
,CA.ColumnB
FROM Table
CROSS APPLY (SELECT SUM(ColumnA) ColumnB FROM Table) CA
You basically define a subquery that outputs an aggregate value that you can have as another column.

Selecting certain value from row based on another value in same row

I have a following table with following data:
Table
Now I want to get all those users (distinct only) who do not have value 5 in Column B. What I mean is user1 has a value 5 in some row, then all user 1 rows are dismissed.
Following result should be produced:
user2 (because value is null)
user3 (no value 5)
How can I do that?
Perhaps the easiest way to do this would be aggregation by user:
SELECT ColumnA
FROM yourTable
GROUP BY ColumnA
HAVING COUNT(CASE WHEN ColumnB = 5 THEN 1 END) = 0;
One method is aggregation:
select columnA
from t
group by columnA
having sum(case when columnB = 5 then 1 else 0 end) = 0;
You can do this by Minus operator
SELECT distinct colA
FROM have
WHERE colB not in(5)
MINUS
SELECT distinct colA
FROM have
WHERE colB=5;
Using NOT EXISTS you can able to get the result
SELECT DISTINCT T1.ColumnA
FROM TableName T1
WHERE NOT EXISTS (
SELECT * FROM TableName T2 WHERE T2.ColumnA = T1.ColumnA AND T2.ColumnB <> 5
)
One more way -
SELECT DISTINCT T1.ColumnA
FROM TableName T1
WHERE T1.ColumnA NOT IN
(
SELECT T2.ColumnA FROM TableName T2 WHERE T2.ColumnB = 5
)

Column update and insert 2 rows within the same table

I have a table named table1 and the value in one columnA is X. So when this value is X we need to insert 2 new rows and update the columnA with values Z and Y.
Is it possible with an insert and Update statement?
I am thinking of below query to update the column but how to insert the two rows.
select * from table1 where columnA = 'x'
Update columnA ='Z'
You could use the following statements to insert in the table
INSERT INTO table1
SELECT 'y' columnA,
columnB,
columnC,
...
FROM table1
WHERE columnA = 'x';
INSERT INTO table1
SELECT 'z' columnA,
columnB,
columnC,
...
FROM table1
WHERE columnA = 'x';
But of course, you still need to provide criteria in WHERE clause to get the specific data you wanted replicated in the same table but with different columnA value. You really need to specify each column.

Joining a table on itself

Is there a better way to write this SQL query?
SELECT *, (SELECT TOP 1 columnB FROM mytable WHERE mytable.columnC = T1.columnC ORDER BY columnD) as firstRecordOfColumnB
FROM
(SELECT * FROM mytable WHERE columnA = 'apple') as T1
Notice that columnC is not the primary key.
If the keyColumns is really a key column (i.e. unique), than the query can definitly be written more elegantly and efficiently...
SELECT
*, columnB
FROM
mytable
WHERE
columnA = 'apple'
This might be better in case of performance:
SELECT
*,
(TOP 1 myLookupTable.columnB FROM mytable AS myLookupTable WHERE myLookupTable.keyColumn = mytable.keyColumn) as firstRecordOfColumnB
FROM
mytable
WHERE
columnA = 'apple'
But for the TOP 1 part I don't know any better solution.
Edit:
If the keyColumn is unique, the data in firstRecordOfColumnB would be the same as in mytable.columnB.
If it's not unique at least you need to sort that data to get a relevant TOP 1, example:
SELECT
*,
(TOP 1 myLookupTable.columnB FROM mytable AS myLookupTable WHERE myLookupTable.keyColumn = mytable.keyColumn
ORDER BY myLookupTable.sortColumn) as firstRecordOfColumnB
FROM
mytable
WHERE
columnA = 'apple'

Getting a distinct value across 2 union sql server tables

I'm trying to get all distinct values across 2 tables using a union.
The idea is to get a count of all unique values in the columnA column without repeats so that I can get a summation of all columns that contain a unique columnA.
This is what I tried (sql server express 2008)
select
count(Distinct ColumnA)
from
(
select Distinct ColumnA as ColumnA from tableX where x = y
union
select Distinct ColumnA as ColumnA from tableY where y=z
)
SELECT COUNT(distinct tmp.ColumnA) FROM ( (SELECT ColumnA FROM TableX WHERE x=y)
UNION (SELECT ColumnA FROM TableY WHERE y=z) ) as tmp
The extra distincts on TableX and TableY aren't necessary; they'll get stripped in the tmp.ColumnA clause. Declaring a temporary table should eliminate the ambiguity that might've prevented your query from executing.
SELECT COUNT(*)
FROM
(
SELECT DISTINCT ColumnA From TableX WHERE x = y
UNION
SELECT DISTINCT ColumnA From TableY WHERE y = z
) t
Using a "UNION" will not return duplicates. If you used "UNION ALL" then duplicate ColumnA values from each table WOULD be return.
To get distinct values in Union query you can try this
Select distinct AUnion.Name,AUnion.Company from (SELECT Name,Company from table1 UNION SELECT Name,Company from table2)AUnion
SELECT DISTINCT Id, Name
FROM TableA
UNION ALL
SELECT DISTINCT Id, Name
FROM TableB
WHERE TableB.Id NOT IN (SELECT Id FROM TableA)