select into using union - ms-access

I need to using both "union" and "into" in a query. These two versions works ok
SELECT x.* INTO
NewTABLE FROM
(SELECT * FROM TABLE1 UNION SELECT * FROM TABLE2) x
Or
SELECT x.* INTO
NewTABLE FROM
(SELECT val1, val2 FROM TABLE1 UNION SELECT val1, val2 FROM TABLE2) x
But what i need is something like this
SELECT x.* INTO
NewTABLE FROM
(SELECT val1, sum(Iif(val2<0,0,val2)) as PositiveVal2 FROM TABLE1
UNION SELECT val1, sum(Iif(val2<0,0,val2)) as PositiveVal2 FROM TABLE2) x
It looks like the sum and/or Iif is the problem. How should I solve this problem!?

You forgot the GROUP BY in your union selects.
SELECT x.* INTO
NewTABLE FROM
(SELECT val1, sum(Iif(val2<0,0,val2)) as PositiveVal2
FROM TABLE1 GROUP BY Val1
UNION
SELECT val1, sum(Iif(val2<0,0,val2)) as PositiveVal2
FROM TABLE2 GROUP BY Val1) x
You must either aggregate or GROUP BY all select fields in an aggregate query.

Related

Selecting distinct values from multiple column of a table with their count

i want to to select distinct values from multiple columns of same table with their count
example
and the output should be like this
Since the OP says in his comment that he uses MYSQL this should work
SELECT data,COUNT(data)
FROM
(
SELECT COL1 data
FROM tableso
UNION ALL
SELECT COL2
FROM tableso
UNION ALL
SELECT COL3
FROM tableso
UNION ALL
SELECT COL4
FROM tableso
UNION ALL
SELECT COL6
FROM tableso
UNION ALL
SELECT COL7
FROM tableso
) finaltable group by data;
SQL FIDDLE: http://sqlfiddle.com/#!2/1f8cf/10
I dont think the accepted answer works on MYSQL
UPDATE:
The op has changed his mind about the database(to MSSQL) and the accepted answer has both db versions
Since you are using Sql Server too, will suggest you this way
Use Table valued constructor to convert the columns to rows then count the name
This will avoid multiple table scan's.
SELECT name,
[count]=Count(1)
FROM yourtable
CROSS apply (VALUES (col1),(COL2),(col3),(col4),(COL6),(col7)) cs (name)
GROUP BY name
Note : This will not work in Mysql
SQLFIDDLE DEMO
Get all column values to one row and find the count
SQL SERVER
;WITH CTE AS
(
SELECT COL1 Name
FROM YOURTABLE
UNION ALL
SELECT COL2
FROM YOURTABLE
UNION ALL
SELECT COL3
FROM YOURTABLE
UNION ALL
SELECT COL4
FROM YOURTABLE
UNION ALL
SELECT COL6
FROM YOURTABLE
UNION ALL
SELECT COL7
FROM YOURTABLE
)
SELECT DISTINCT Name,COUNT(Name) OVER(PARTITION BY Name) [COUNT]
FROM CTE
MYSQL
SELECT Name,COUNT(*) [COUNT]
(
SELECT COL1 Name
FROM #TEMP
UNION ALL
SELECT COL2
FROM #TEMP
UNION ALL
SELECT COL3
FROM #TEMP
UNION ALL
SELECT COL4
FROM #TEMP
UNION ALL
SELECT COL6
FROM #TEMP
UNION ALL
SELECT COL7
FROM #TEMP
)TAB
GROUP BY Name

How to show MIN value with whole table

I have table like:
id col1 col2
1 a 55
2 b 77
In result i want to see:
id col1 col2 MIN(col2)
1 a 55 55
2 b 77
Something like that, or in other case, how i can get one minimum value with whole table.
You can use a CROSS JOIN with a subquery which will select the min(col2) value for the entire table:
select t1.id,
t1.col1,
t1.col2,
t2.minCol2
from yourtable t1
cross join
(
select min(col2) minCol2
from yourtable
) t2
See SQL Fiddle with Demo.
If you want to expand this to only show the min(col2) value on the first row, then you could use user-defined variables:
select id,
col1,
col2,
case when rn = 1 then mincol2 else '' end mincol2
from
(
select t1.id,
t1.col1,
t1.col2,
t2.minCol2,
#row:=case when #prev:=t1.id then #row else 0 end +1 rn,
#prev:=t1.id
from yourtable t1
cross join
(
select min(col2) minCol2
from yourtable
) t2
cross join (select #row:=0, #prev:=null) r
order by t1.id
) d
order by id
See SQL Fiddle with Demo
If you had more than one column that you want to compare, then you could unpivot the data using a UNION ALL query and then select the min value for the result:
select t1.id,
t1.col1,
t1.col2,
t2.MinCol
from yourtable t1
cross join
(
select min(col) MinCol
from
(
select col2 col
from yourtable
union all
select col3
from yourtable
) src
) t2
See SQL Fiddle with Demo
You can't. The number of columns is fixed, so you can get the minimum value on all the rows as described by #bluefeet.
You could get it on a smaller number of rows (typically 1) by using the logic:
(case when t2.minCol2 = t1.col2 then t2.minCol2 end)
But this would put NULLs on the other rows.

MySQL: A sum from 3 different tables

How can I sum the columns of 3 tables?
I have table1, table2, and table3 with the column 'revenue'.
I can do SELECT SUM(REVENUE) FROM TABLE1 but what do i do for all of them?
I tried: SELECT SUM(
table1.Revenue+
table2.Revenue +
table3.Revenue
)
FROM
table1,
table2,
table3' but it doesn't work...
Any ideas? Thanks!
select sum(rev) as trev
from
(
SELECT SUM( Revenue) as rev FROM table1
union all
SELECT SUM( Revenue) as rev FROM table2
union all
SELECT SUM( Revenue) as rev FROM table3
) as tmp
You need to add all of the individual sums together:
SELECT (SUM(table1.Revenue) + SUM(table2.Revenue) + SUM(table3.Revenue))
AS total_rev FROM table1, table2, table3
select sum( revenue )
from (
select revenue from table1
union
select revenue from table2
union
select revenue from table3
)
SELECT SUM(REVENUE) FROM (
SELECT REVENUE FROM TABLE1
UNION ALL
SELECT REVENUE FROM TABLE2
UNION ALL
SELECT REVENUE FROM TABLE3
) revenues

MySQL GROUP BY and HAVING

I'm grouping my results based on a column X and I want to return the rows that has highest Column Y's value in the group.
SELECT *
FROM mytable
GROUP BY col1
HAVING col2 >= (SELECT MAX(col2)
FROM mytable AS mytable2
WHERE mytable2.col1 = mytable.col1 GROUP BY mytable2.col1)
I want to optimize the query above. Is it doable without sub-queries?
I found the solution and it's simpler than you think:
SELECT * FROM (SELECT * FROM mytable ORDER BY col2 DESC) temp GROUP BY col1
Runs in 5 milliseconds on 20,000 rows.
Using a derived table/inline view for a JOIN:
SELECT x.*
FROM mytable x
JOIN (SELECT t.col1,
MAX(t.col2) AS max_col2
FROM MYTABLE t
GROUP BY t.col1) y ON y.col1 = x.col1
AND y.max_col2 >= x.col2
Be aware that this will duplicate x records if there's more than one related y record. To remove duplicates, use DISTINCT:
SELECT DISTINCT x.*
FROM mytable x
JOIN (SELECT t.col1,
MAX(t.col2) AS max_col2
FROM MYTABLE t
GROUP BY t.col1) y ON y.col1 = x.col1
AND y.max_col2 >= x.col2
The following is untested, but will not return duplicates (assuming valid):
SELECT x.*
FROM mytable x
WHERE EXISTS (SELECT NULL
FROM MYTABLE y
WHERE y.col1 = x.col1
GROUP BY y.col1
HAVING MAX(y.col2) >= x.col2)
Your Col2 never be > then MAX(col2) so i suggest to use col2 = MAX(col2)
so HERE is the QUERY
SELECT * FROM mytable GROUP BY col1 HAVING col2 = MAX( col2 )

calculate frequency using sql

I have a table in MySQL:
Col1 | Col2
a A
a B
c C
a B
i want to create a table like this:
col1 | col2 | freq
a A 0.33
a B 0.67
col1 is a specified item in Col1. col2 is distinct item that has occured with the specified item(i.e. a). freq column is the frequency of appearence of item in col2.
Can someone give me a hint of how to create such a query? Thanks a lot.
try this:
Select A.Col1, A.Col2, A.Count1 * 1.0 / B.Count2 As Freq
From (
Select Col1, Col2, Count(*) As Count1
From YourTableName
Group By Col1, Col2
) As A
Inner Join (
Select Col1, Count(*) As Count2
From YourTableName
Group By Col1
) As B
On A.Col1 = B.Col1
You can also use this which is coded in SQL server
DECLARE #Count INT;
SELECT #Count = COUNT(1) FROM YourTableName WHERE Col1 = 'a'
SELECT Col1, Col2, CAST(COUNT(1)* 1.00 /#Count AS DECIMAL(4,2) ) AS Frequency
FROM YourTableName
WHERE Col1 = 'a'
GROUP BY Col1, Col2
this way you have a better performance
With window functions
SELECT Col1, Col2, Count1*1.0 / Count2 AS freq
FROM (
SELECT
Col1,
Col2,
COUNT() OVER(PARTITION BY Col1, Col2) AS Count1,
COUNT() OVER(PARTITION BY Col1) AS Count2
FROM YourTableName
)
GROUP BY Col1, Col2