Mysql SELECT UNION returning wrong results? - mysql

I have this single query.
$sql = "SELECT * FROM `my_table` WHERE type!='' AND (page_option='0' OR page_option='1') ORDER BY type ASC";
The first three results for the column scenario returned are a1,d3,e1.
Now when i do a UNION ALL with other identical tables:
$sql = "SELECT * FROM `my_table`
WHERE type!='' AND (page_option='0' OR page_option='1')
UNION ALL
SELECT * FROM `my_table_2`
WHERE type!='' AND (page_option='0' OR page_option='1')
UNION ALL
SELECT * FROM `my_table_3`
WHERE type!='' AND (page_option='0' OR page_option='1')
ORDER BY type ASC";
I loop through the results and the first three columns for my_table are e1,e1,e1.
Each table has a column called type, which identifies the table the result comes from. So for the union query results i added a condition to display only scenarios from my_table
if($type=="my_table") {
echo $scenario;
}
The scenarios should be identical to the single query but they aren't.
How do i solve?

Your assumption is wrong. Order Isnt guaranteed unless you use ORDER BY
In your case you are order only by type so the order of other fields can be random
You can find a nice explanation and examples here:
http://sqlblog.com/blogs/alexander_kuznetsov/archive/2009/05/20/without-order-by-there-is-no-default-sort-order.aspx

Related

How do select data with IF ELSE statement in a MySQL query

I get data from MySQL with if statement as code below. but I get an error:
Error Code: 1241. Operand should contain 1 column(s).
so can someone can help me?
I can not put it into the procedure, because I am using spring + mybatis in the project and i will put this code into them.
SELECT IF((SELECT COUNT(*) FROM table1 WHERE someField = 'A') < 0,
(SELECT * FROM table2 WHERE someField = 'A'),
(SELECT * FROM table1 WHERE someField = 'A'))
From the comments: I wanna get data of 1 in 2 tables when table 1 don't have data I will get data from table 2.
That sounds like union all and not exists:
select * from table1 where someField = 'A'
union all
select * from table2 where not exists(select 1 from tabe1 where someField = 'A'
Note that, for this to work, both tables must contain exactly the same number of columns, whith aligned datatypes. You should really be enumerating the columns that you want to show in the resultset in both unioned queries, to avoid any possible ambiguity. If needed, you can cast columns or add litteral values to any or both of the resultset to align the resultsets (without seeing your actual data structures, I cannot tell how to do).

Mysql: Is it possible to use a subquery inside a from clause in order to pick the table name from another table

I was wondering if there's any way to add a subquery with a switch case to the form clause of my select query in order to select a table based on a condition.
For example:
select a.*
from (select (case when (table2.column = 'something')
then (table2.tablename1)
else (table2.tablename2)) as tablename
from table2
where table2.column2 = 'blabla'
limit 1
) a
I tried to write that in many variation & so far non of them worked.
On the most successful tryouts (when I got no mysql errors) it returned the name of the table as the result itself (for example: the value that's in table2.tablename2). I understand why it did that (because I selected everything from a select results...) but how can I use the tablename from the results in order to set the table on the main query?
Hope that make sense...
Any idea?

MySQL how to group into subgroups of rows

I have this DB: (note id is unique)
I am trying to get this:
What would be an efficient SQL query to achieve this?
SELECT
DISTINCT
foo2.group_id AS group_id,
if(foo1.group_id = foo2.group_id, foo1.id, NULL) AS id,
if(foo1.group_id = foo2.group_id, foo1.some_attr, NULL) AS some_attr
FROM mytable AS foo1
JOIN
(SELECT DISTINCT group_id FROM mytable) as foo2
ORDER BY group_id, id
You seem to be mixing a result set with formatting of the result set. SQL result sets are tables of consistent rows. The closest you can come is to change the sequence of your column names in the SELECT statement. You'll have to add your own line breaks at time of presentation.

Concat 2 columns in a string, then get a count for each concatenation

I am trying to concatenate 2 columns, then count the number of rows i.e. the total number of times the merged column string exists, but I don't know if it is possible. e.g:
SELECT
CONCAT(column_1,':',column_2 ) as merged_columns,
COUNT(merged_columns)
FROM
table
GROUP BY 1
ORDER BY merged_columns DESC
Note: the colon I've inserted as a part of the string, so my result is something like 12:3. The 'count' then should tell me the number of rows that exist where column_1 =12 and column_2 = 3.
Obviously, it tells me 'merged_columns' isn't a column as it's just an alias for my CONCAT. But is this possible and if so, how?
Old question I know, but the following should work without a temp table (unless I am missing something):
SELECT
CONCAT(column_1,':',column_2 ) as merged_columns,
COUNT(CONCAT(column_1,':',column_2 ))
FROM
table
GROUP BY 1
ORDER BY merged_columns DESC
You can try creating a temp table from your concatenation select and then query that:
SELECT CONCAT(column_1,':',column_2 ) AS mergedColumns
INTO #temp
FROM table
SELECT COUNT(1) AS NumberOfRows,
mergedColumns
FROM #temp
GROUP BY mergedColumns
Hope this answer is what your are looking for.
Try this
SELECT
CONCAT(column_1,column_2 ) as merged_columns,
COUNT(*)
FROM
table
GROUP BY merged_columns
ORDER BY merged_columns DESC

Mysql Union repeating results

I have the following select but it repeats the results of the second inner select 3 times.
Can anyone tell me why this is.
Also when I get the results how can I know which table the results came from. Home_content or facilities_table.
SELECT * FROM (SELECT hm_id, hm_name, hm_summary,
MATCH (hm_name, hm_summary) AGAINST ('test') AS score FROM home_content
WHERE MATCH (hm_name, hm_summary) AGAINST ('test') UNION SELECT fac_id,fac_name,
fac_summary, MATCH (fac_title, fac_summary) AGAINST ('test') AS score FROM
facilities_table WHERE MATCH (fac_title, fac_summary) AGAINST ('test')) a
ORDER BY SCORE DESC
Thanks in advance
Can't see why you are getting duplicates from this query unless:
There are duplicates in the source table
The same data appears in home_content and facilties_table (perhaps one is a view of the other?)
The second part of question as to deciding which table the contents of the union comes from is easily address by adding a constant column to each query of the union giving you something like this:
SELECT * FROM (SELECT 1,hm_id, hm_name, hm_summary,
MATCH (hm_name, hm_summary) AGAINST ('test') AS score FROM home_content
WHERE MATCH (hm_name, hm_summary) AGAINST ('test') UNION SELECT 2,fac_id,fac_name,
fac_summary, MATCH (fac_title, fac_summary) AGAINST ('test') AS score FROM
facilities_table WHERE MATCH (fac_title, fac_summary) AGAINST ('test')) a
ORDER BY SCORE DESC
In this case the initial column should be 1 for the home_content table and 2 for the facilities_table. Obviously string constants could be used in a similair style if that suited you better.