Using a value from one query in second query sql - sql

SELECT AS, COUNT(*)
FROM Table1
HAVING COUNT(AS)>1
group BY AS;
This produces the result
AS COUNT
5 2
I then want to use the AS value in another query and only output the end result. Is this possible.i was thinking something like.
SELECT *
FROM
TABLE 2
Where AS =(
SELECT AS, COUNT(*)
FROM Table1
HAVING COUNT(AS)>1
group BY AS;
);

This is called a subquery. To be safe, you would use in instead of = (and as is a bad name for a column, because it is a SQL key word):
SELECT *
FROM TABLE2
WHERE col IN (SELECT col
FROM Table1
GROUP BY col
HAVING COUNT(col) > 1
);
Your first query is also incorrect, because the having clause goes after the group by.

You could use a subquery with the in operator:
SELECT *
FROM table2
WHERE AS IN (SELECT AS
FROM table1
GROUP BY AS
HAVING COUNT(*) > 1)

Related

Subtraction of two SELECT statements in SQL (redshift)

Can someone explain why the below doesn't work?
((SELECT COUNT(*) FROM Table1) - (SELECT Count(Metric) FROM Table1)) as X
Count(*) will give me all the rows in the table and Count(Metric) will give me the non-null values in the Metric column. So the difference between these will give me the number of null values in the Metric column and I have labelled this column X. I just want the difference between the two in Column X but not sure why it isn't working.
By the way, I know I can get it to work via the below:
SELECT COUNT(*) as a, count(metric) as b, COUNT(*)-COUNT(metric) as c
You would need to select the result:
SELECT ((SELECT COUNT(*) FROM Table1) - (SELECT Count(Metric) FROM Table1)) as X
But it is simpler to use conditional aggregation:
SELECT SUM(CASE WHEN Metrics IS NULL THEN 1 ELSE 0 END) X FROM table1
A SELECT query needs to start with SELECT (or WITH or a parenthesis if the query is a compound query with a set operator such as UNION ALL).
One method is:
SELECT ((SELECT COUNT(*) FROM Table1) - (SELECT Count(Metric) FROM Table1)) as X
A better method is:
SELECT COUNT(*) - Count(Metric) as X
FROM Table1
Not sure about amazon-redshift, but in standard SQL I would just count the records where the field is null instead of counting all minus where they are not null.
SELECT COUNT(*) FROM Table1 WHERE Metric IS NULL;

Is it possible to use a subquery more than once?

I was wondering if it was possible to use a subquery in SQL more than once.
For example:
with subQuery as (
select id from someTable1
)
update someTable2
set someValue = 1
where id in (select * from subQuery)
select * from someTable2
where id in (select * from subQuery)
...
As of right now, SQL throws an error on the (select * from subQuery) in the select * someTable2 clause saying "Invalid Object Name subQuery". So is there a way to use subQuery more than once without having to add a table or run the query multiple times changing out the first statement?
A CTE is in scope only for a single query, but a query can both UPDATE and OUTPUT data. eg
with subQuery as (
select id from someTable1
)
update someTable2
set someValue = 1
output inserted.*
where id in (select * from subQuery)

How to write the query that returns records where some column value appears more than once?

I have a table that has column with statuses. I need to write the query that returns records where some column value appears more than once?
Something like this:
select * from Table1
where COUNT(StatusID = 6) > 1
You can write your query like following:
SELECT *
FROM Table1
WHERE StatusID IN
(
SELECT StatusID
FROM (SELECT StatusID,Count(*) AS cnt FROM Table1 WHERE StatusID=6
GROUP BY StatusID
HAVING COUNT(*) > 1) AS tbl
)

Pattern matching SQL on first 5 characters

I'm thinking about a SQL query that returns me all entries from a column whose first 5 characters match. Any ideas?
I'm thinking about entries where ANY first 5 characters match, not specific ones. E.g.
HelloA
HelloB
ThereC
ThereD
Something
would return the first four entries:
HelloA
HelloB
ThereC
ThereD
EDIT: I am using SQL92 so cannot use the left command!
Try this :
SELECT *
FROM YourTable
WHERE LEFT(stringColumn, 5) IN (
SELECT LEFT(stringColumn, 5)
FROM YOURTABLE
GROUP BY LEFT(stringColumn, 5)
HAVING COUNT(*) > 1
)
SQLFIDDLE DEMO
This selects the first 5 characters, groups by them and returns only the ones that happen more than once.
Or with Substring:
SELECT * FROM YourTable
WHERE substring(stringColumn,1,5) IN (
SELECT substring(stringColumn,1,5)
FROM YOURTABLE
GROUP BY substring(stringColumn,1,5)
HAVING COUNT(*) > 1)
;
SQLFIDDLE DEMO
Sounds easy enough...
In SQL Server this would be something along the lines of
where Left(ColumnName,5) = '12345'
Try
Select *
From tbl t1
Where exists (
Select 1
From tbl t2
Where left(t1.str, 5) = left(t2.str)
Group by left(t2.str, 5)
Having count(1) > 1
)
You didn't specify your DBMS. If it supports Windowed Aggregate functions it's:
select *
from
(
select
tab.*,
count(*) over (partition by substring(col from 1 for 5) as cnt
from tab
) as dt
where cnt > 1
You want to work with a CTE approach.
Something like this:
with CountriesCTE(Id, Name)
as (
select Id, Name from Countries
)
select distinct Countries.Name
from CountriesCTE, Countries
where left(CountriesCTE.Name,5) = left(Countries.Name,5) and CountriesCTE.Id <> Countries.Id

Count rows in more than one table with tSQL

I need to count rows in more than one table in SQL Server 2008. I do this:
select count(*) from (select * from tbl1 union all select * from tbl2)
But it gives me an error of incorrect syntax near ). Why?
PS. The actual number of tables can be more than 2.
In case you have different number of columns in your tables try this way
SELECT count(*)
FROM (
SELECT NULL as columnName
FROM tbl1
UNION ALL
SELECT NULL
FROM tbl2
) T
try this:
You have to give a name to your derived table
select count(*) from
(select * from tbl1 union all select * from tbl2)a
I think you have to alias the SELECT in the FROM clause:
select count(*)
from
(
select * from tbl1
union all
select * from tbl2
) AS SUB
You also need to ensure that the * in both tables tbl1 and tbl2 return exactly the same number of columns and they have to be matched in their type.
I don't like doing the union before doing the count. It gives the SQL optimizer an opportunithy to choose to do more work.
AlexK's (deleted) solution is fine. You could also do:
select (select count(*) from tbl1) + (select count(*) from tbl2) as cnt