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.
Related
Let's say I have a table like this -
id
number
1
1
2
1
3
1
I want to return the second largest number, and if there isn't, return NULL instead. In this case, since all the numbers in the table are the same, there isn't the second largest number, so it should return NULL.
These codes work -
SELECT IFNULL((
SELECT number
FROM (SELECT *, DENSE_RANK() OVER(ORDER BY number DESC) AS ranking
FROM test) r
WHERE ranking = 2), NULL) AS SecondHighestNumber;
However, after I changed the order of the query, it doesn't work anymore -
SELECT IFNULL(number, NULL) AS SecondHighestNumber
FROM (SELECT *, DENSE_RANK() OVER(ORDER BY number DESC) AS ranking
FROM test) r
WHERE ranking = 2;
It returns blank instead of NULL. Why?
Explanation
This is something of a byproduct of the way you are using subquery in your SELECT clause, and really without a FROM clause.
It is easy to see with a very simple example. We create an empty table. Then we select from it where id = 1 (no results as expected).
CREATE TABLE #foo (id int)
SELECT * FROM #foo WHERE id = 1; -- Empty results
But now if we take a left turn and turn that into a subquery in the select statement - we get a result!
CREATE TABLE #foo (id int)
SELECT (SELECT * FROM #foo WHERE id = 1) AS wtf; -- one record in results with value NULL
I'm not sure what else we could ask our sql engine to do for us - perhaps cough up an error and say I can't do this? Maybe return no results? We are telling it to select an empty result set as a value in the SELECT clause, in a query that doesn't have any FROM clause (personally I would like SQL to cough up and error and say I can't do this ... but it's not my call).
I hope someone else can explain this better, more accurately or technically - or even just give a name to this behavior. But in a nutshell there it is.
tldr;
So your first query has SELECT clause with an IFNULL function in it that uses a subquery ... and otherwise is a SELECT without a FROM. So this is a little weird but does what you want, as shown above. On the other hand, your second query is "normal" sql that selects from a table, filters the results, and lets you know it found nothing -- which might not be what you want but I think actually makes more sense ;)
Footnote: my "sql" here is T-SQL, but I believe this simple example would work the same in MySQL. And for what it's worth, I believe Oracle (back when I learned it years ago) actually would cough up errors here and say you can't have a SELECT clause with no FROM.
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?
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.
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
I'm using PDO with MySQL.
I want to select all rows from a given table with distinct values in a given column, but SELECT DISTINCT column_name FROM table returns the rows with only that column_name. Therefore I can't access the other row's columns.
I've been searching for answers and it looks like SELECT DISTINCT column_name FROM table is supposed to return all the rows with distinct values inside column_name with all the row's columns. However, I only get the column I want distinc'ed:
Array
(
[image] => leather_helmet.jpg
// there are supposed to be more fields here...
)
May this be a PDO's bug or am I doing something wrong?
Thanks in advance! :)
If you want only 1 column distinct you have to think of which record you want for the other columns. For instance if you like the min id record for the distinct column then you can do
SELECT *
FROM armor_unsealed
WHERE id IN
(
SELECT min(id)
FROM armor_unsealed
WHERE piece=:piece
GROUP BY image
)'