mysql storing subquery in column and performing where condition - mysql

i am performing a sub query in mysql which is like
select col1, col2 , (select col3 from table2) as 'data'
from table1
where not data is null
how should i get data in where clause. IS it POSSIBLE

One way to do this is :
SELECT *
FROM (
select col1, col2 , (select col3 from table2) as 'data'
from table1
)t
WHERE data IS NOT NULL
As you see there I have created on derived table t for your query, now result of your query is treated as Table(temp table) and having columns as col1,col2 and col3, Using this result set we can able to access col3 in where clause .
Note - assuming that select col3 from table2 returns single value as per OP's comments

Use cross join:
select t1.col1, t1.col2, t2.col3 as data
from table1 t1 cross join
(select col3 from table2) t2
where t2.col3 is not null;

Related

With As Clause Not recognized MySQL

I am trying to use a with as clause in a query.
WITH NAME AS
(
SELECT col1,
col2
FROM TABLE1
)
SELECT col2,
col3
FROM TABLE2
WHERE col2 in (NAME.col1)
The query placed in the with as clause works on it's own but I get this error:
Unknown column NAME.'col1' in 'where clause'
I am more familiar with oracle so this may have caused some error by carrying something over.
Is the order of the clauses wrong and With As comes after where?
I think you do not need the CTE.
SELECT col2,
col3
FROM TABLE2
WHERE col2 in (SELECT col1 FROM TABLE1)
should work
If you want to use CTE (for what reason ever), you have to select from the table
WITH NAME AS
(
SELECT col1,
col2
FROM TABLE1
)
SELECT col2,
col3
FROM TABLE2
WHERE col2 in (select col1 from name)

MYSQL select same column name as alias in union not working

I have a simple MYSQL query that unions two tables:
SELECT * FROM (
SELECT col1 AS col1A FROM table1
UNION
SELECT col1 AS col1B FROM table2
) AS t WHERE col1A <> col1B
I have a column called col1 in both tables and I need to select only rows that have a different value of that column so I select them as aliases. When I run this query I got:
Unknown column 'col1B' in 'where clause'
Table1 data:
col1
----
test
Table2 data:
col1
----
test
The query should return no rows as each value in col1 in table1 is equal to each value in col1 in table2 instead it returns that col1 in table2 is unknown although I select it as an alias
I think you need to look up the appropriate usage of UNION. It will return all results from first query combined with all results from the second query. This results in a single dataset, with a single column (not col1 and col2), just col1 in this case.
Assuming you're trying to get all records in table1 that don't exist in table2, you can use NOT EXISTS:
SELECT col1
FROM table1 t1
WHERE NOT EXISTS (
SELECT 1
FROM table2 t2
WHERE t1.col1 = t2.col1
)
Why Error 1054 is being returned by OP query
The error that's being returned is because the name assigned to a column from the result of a UNION is taken from the first SELECT.
You can observe this by running a simple example:
SELECT 1 AS one
UNION
SELECT 2 AS two
The resultset returned by that query will contain a single column, the name assigned to the column will be one, the column name from the first SELECT. This explains why you are getting the error from your query.
One way to return rows with no match
To return values of col1 from table1 which do not match any value in the col1 column from table2...
one option to use an anti-join pattern...
SELECT t1.col1
FROM table1 t1
LEFT
JOIN table2 t2
ON t2.col1 = t1.col1
WHERE t2.col1 IS NULL
The LEFT JOIN operation returns all rows from table1, along with any "matching" rows found in table2. The "trick" is the predicate in the WHERE clause... any "matching" rows from table2 will have a non-NULL value in col1. So, if we exclude all of the rows where we found a match, we're left with rows from table1 that didn't have a match.
If we want to get rows from table2 that don't have a "matching" row in table1, we can do the same thing, just flipping the order of the tables.
If we combine the two sets, but only want a "distinct" list of "not matched" values, we can use the UNION set operator:
SELECT t1.col1
FROM table1 t1
LEFT
JOIN table2 t2
ON t2.col1 = t1.col1
WHERE t2.col1 IS NULL
UNION
SELECT s2.col1
FROM table2 s2
LEFT
JOIN table1 s1
ON s1.col1 = s2.col1
WHERE s1.col1 IS NULL
--
Finding out which table the non-matched value is from
Sometimes, we want to know which query returned the value; we can get that by including a literal value as a discriminator in each query.
SELECT 'table1' AS src
, t1.col1
FROM table1 t1
LEFT
JOIN table2 t2
ON t2.col1 = t1.col1
WHERE t2.col1 IS NULL
UNION
SELECT 'table2' AS src
, s2.col1
FROM table2 s2
LEFT
JOIN table1 s1
ON s1.col1 = s2.col1
WHERE s1.col1 IS NULL
ORDER BY 2
A different (usually less performant) approach to finding non-matching rows
An entirely different approach, to returning an equivalent result, would be do something like this:
SELECT q.col1
FROM ( SELECT 't1' AS src, t1.col1 FROM table1 t1
UNION
SELECT 't2' AS src, t2.col1 FROM table2 t2
) q
GROUP BY q.col1
HAVING COUNT(DISTINCT q.src) < 2
ORDER BY q.col1
(The inline view q will be "materialized" as a derived table, so this approach can be expensive for large sets, and this approach won't take advantage of indexes on col1 to perform the matching.) One other small difference between this and the anti-join approach: this will omit a col1 value of NULL if a NULL exists in both tables. Aside from that, the resultset is equivalent.

MySQL count on Grouping

I want to count the number of times a grouping occurs in a query.
SELECT COL1,
COL2,
*(count COL1)*
FROM TABLE
GROUP BY COL1, COL2
So I'm expecting to see the results like so:
COL1, COL2, Count
A, A, 1
A, B, 2
B, A, 1
B, B, 2
B, C, 3
Count(*) will give me the sum of the grouped row which is what I don't want, but I just cant seem to get my head round it or find a way to do it. Anyway, thanks in advance.
You should add auto_increment column to make an order. After that, try something like this:
SELECT a.col1, a.col2,
(SELECT Count(*) From T1 c
WHERE c.col1 = a.col1
AND c.ID <= a.ID) as count
FROM T1 a;
SQL Fiddle
OR Without auto_increment Try this:
SELECT col1, col2,
(select count(*) from T1 t2
where t2.col2 <= t1.col2 and
t2.col1 = t1.col1
) as Enumeration
FROM T1 t1
GROUP BY col1, col2;
SQL Fiddle
Your query (with the parentheses appropriately placed) does what you want:
SELECT COL1, COL2, count(*)
FROM TABLE
GROUP BY COL1, COL2;
If you want the sum of a column, then use the sum() function.
EDIT:
If you are trying to enumerate the groups (despite what the question is asking in rather clear English), you can do:
SELECT col1, col2,
(select count(*)
from table t2
where t2.col1 = t.col1 and
t2.col2 <= t.col2
) as Enumeration
FROM table t1
GROUP BY col1, col2;

MySQL Query - not interested in using inner query

I have a query say,
select col1,col2 from table1;
which return 2 columns of multiple rows. I want to use these two values in where condition of another query. Something like
select col3,col4 from table2 where col5=col1 and col6=col2;
where col1 and col2 are the resultant values of the first query.
Currently I have used inner query something like
select col3,col4 from table2
where col5 in (select col1 from table1)
and col6 in (select col2 from table1);
But I dont want to use inner query like the one shown above as it slows down bring results.
Please suggest.
JOIN them instead of using IN's like so:
SELECT t2.col3, t2.col4
FROM table2 t2
INNER JOIN
(
SELECT col1, col2
FROM table1
) t1 ON t2.col5 = t1.col1 AND t2.col6 = t1.col2
Note that, you didn't need to select specific columns in the second table. You can JOIN the second table table1 directly like so:
SELECT t2.col3, t2.col4
FROM table2 t2
INNER JOIN table1 t1 ON t2.col5 = t1.col1
AND t2.col6 = t1.col2

Combining outputs of multiple queries into one

1.select col1,col2 from table1 where condition1=<<value1>>
UNION ALL
select col1,col2 from table2 condition1=<<value2>>;
2. `select col1 from table3;`
3. I need to write the 3rd query where i need the output of col1,col2 from table1 based on the col1 (sort based on col1 from table3).
I can do this way
create table as temp_table as
select col1,col2 from table1 where condition1=<<value1>>
UNION ALL
select col1,col2 from table2 condition1=<<value2>>;
SELECT t1.col1,t1.col2
FROM temp_table t1
LEFT OUTER JOIN table3 t2 ON t1.col2=t2.col2
order by t2.col1;
I want in a single query(in mysql ) & not using temp table.
Any thoughts? Thanks.
You can use the unioned result as subselect.
Look into subqueries. They're kind of like a temporary table that only exists while the query is running.
Select T.A, T.B from
(select col1 as A,col2 as B from table1 where condition1=<<value1>>
UNION ALL
select col1,col2 from table2 condition1=<<value2>>) as T,
table3 as T2
where T.A = T2.col1
order by t2.col1