I need help with CONCAT function. I have two select queries and the result of every query is one column. I need to merge this two columns in one. Is that possible? Beacuse, I can't get result even if I try with simple select queries like:
SELECT owner FROM table WHERE number="value1";
SELECT number FROM table WHERE owner="value2" AND number IS NOT null;
These queries work and throw 3 rows like result. But, if I want to merge them in one column using CONCAT - that doesn't work. Do you know why?
SELECT CONCAT(SELECT owner FROM table WHERE number="value1",
SELECT number FROM table WHERE owner="value2" AND number IS NOT null
) as NEW_COLUMN FROM table;
I think you want this:
SELECT CONCAT(owner, number) newCol1
FROM yourTable
WHERE number="value1"
OR (owner="value2" AND number IS NOT null)
SELECT
CONCAT(owner, number) as NEW_COLUMN
FROM
table
WHERE
owner = "value2"
AND number = "value1"
AND number IS NOT NULL
The fundamental reason is that the DB cannot concatenate two different SELECTs which might have a different number of rows.
What you need to do is to re-formulate your query in terms of a JOIN.
For example suppose we have this table:
owner number
John value1
value2 123456
Your first query:
SELECT owner FROM table WHERE number="value1";
will return "John". The second one
SELECT number FROM table WHERE owner="value2" AND number IS NOT null;
will return "123456".
If you CONCAT the two values you would therefore get "John 123456".
First of all, is this the expected behaviour of the query you want? What happens is there is a third row with owner=Jack and number=value1, so that the first query returns TWO rows "John" and "Jack"?
One thing you could look into is the CROSS JOIN syntax.
SELECT CONCAT (table1.owner, ', ', table2.number) AS new_column
FROM ( SELECT owner FROM table WHERE number="value1" ) AS tablel1
CROSS JOIN
(SELECT number FROM table WHERE owner="value2" AND number IS NOT null ) AS table2;
Note that if the first query returns three rows and the second four rows, the combined query will return 3*4 = 12 rows.
Related
I have two unrelated queries. I need to select records from first query whose column value does not contain any of the values returned from another query. Please suggest a way to do this.
Let us say, first query returns these records:
abc_123_xyz
def_456_hij
lmn_opq
rst_uvw
Let us say, second query returns these records:
123
456
The expected result is:
lmn_opq
rst_uvw
I have written a query which matches the result and it works fine. But when I add NOT LIKEcondition, it fails. Please help!
select o.name
from (select pattern from PATTERN) p,
objects o
where o.name like '%'||p.pattern||'%';
Assuming PATTERN table returns 123,456, it matches the values abc_123_xyz, def_456_hij correctly. However if I execute above query with NOT LIKE condition, it fails to return only the other two records. Instead it returns all four values. What is wrong here?
The query with NOT LIKE will return all the rows, and it will return the rows that don't match anything TWICE.
You are joining the two tables, which means you are getting an output row for every combination of a row from the first table and a row from the second table. Total 8 rows (4 * 2).
Then just TWO of those rows are rejected by the WHERE filter - one row, the one that contains 123 , is rejected by the condition NOT LIKE ...123... (but it is still include the other time, because it does meet the condition NOT LIKE ...456...).
What you want is a SEMI-JOIN: you want all the rows from one table (counted only one time!) that don't match anything in the second table. In a join like you wrote, if a row from the first table doesn't match one pattern, it will be included in the output, even if it does match another pattern.
What you need is something like this:
select name
from objects o
where not exists ( select pattern from p where o.name like '%' || pattern || '%')
;
you could use a left join and
select o.name
from objects o
left join PATTERN p on o.name like '%'||p.pattern||'%'
where p.pattern is null ;
I hope you can help me with that topic.
I have one table, the relevant fields are VARCHAR id, VARCHAR name and date
3DF0001AB TESTING_1 2017-04-04
3DF0002ZG TESTING_2 2017-04-03
3DF0003ER TESTING_1 2017-04-01
3DF0004XY TESTING_1 2017-03-26
3DF0005UO TESTING_3 2017-03-25
The goal is to retrieve two entries for every name (>500), sorted by date. As I can just use database queries I tried following approach. Get one id for every name, UNION the result with the same query, but excluding the ids from the first set.
First step was to get one entry for every name. Result as expected, one id for every name.
SELECT id FROM table GROUP BY name;
Second step; using the above statement in the WHERE clause to receive results, that are not in the first result:
SELECT id FROM table WHERE id NOT IN (SELECT id FROM table GROUP BY name)
But here the result is empty, then I tried to invert the WHERE by using WHERE id IN instead of NOT IN. Expected result was that the same ids would show up when just using the subquery, result was all ids from the table. So I assume that the subquery delivers a wrong result, because when I copy the ids manually -> id IN ("3DF0001AB", ...) it works.
So maybe someone can explain the behavior and/or help to find a solution for the original problem.
This is a really bad practice:
SELECT id
FROM table
GROUP BY name;
Although MySQL allows this construct, the returned id is from an indeterminate row. You can even get different rows when you run the same query at different times.
A better approach is to use an aggregation function:
SELECT MAX(id)
FROM table
GROUP BY name;
Your real problem, though, is slightly different. When you use NOT IN, no rows are returned if any value in the IN list is NULL. That is how NOT IN is defined.
I would recommend using NOT EXISTS or LEFT JOIN instead, because their behavior is more intuitive:
SELECT t.id
FROM table t LEFT JOIN
(SELECT MAX(id) as id
FROM table t2
GROUP BY name
) tt
ON t.id = tt.id
WHERE tt.id IS NULL;
Can I divide the values in a column by the number of rows returned in the query, using a single query?
For example, I select some numeric value from a table based on some condition:
select value from table where ...
Let's say it returns N rows and I want the returned values divided by the number of rows returned:
select value / N from table where ...
It can be done with several queries (e.g. after the first query, I query the number of rows and do the query again). But can it be done in a single query with some SQL trick without query condition duplication, so that the actual selection (the WHERE part) which may be complicated runs only once?
You can do it in a single query, but as far as I know, with mysql you have to repeat the condition:
select
value/#cnt from
table1
INNER JOIN (select #cnt = count(*)
FROM table1 WHERE [the same condition as in main query]) ON (1=1)
WHERE condition
Or you can just
SELECT value/(SELECT COUNT(*) FROM table1 WHERE ...)
FROM table1
WHERE ...
I believe optimizer should generate the same execution plan for both queries.
The issue here is suppose if i want to use two queries seperated by UNION, the query is as
$query=(select a.name,a.age,b.country,b.state from a,b where a.aid=b.bid) UNION (select a.name,a.age,c.profession,c.salary from a,c where a.anid=c.cid)
here the result would only show the first query's result , Any way in which i could display the result of 2nd query also down to the result of first query using UNION. Expecting any help on this. Thanks
Are you after
(
select a.name,a.age,b.country,b.state,null as profession,null as salary
from a,b
where a.aid=b.bid
)
UNION
(
select a.name,a.age,null,null,c.profession,c.salary
from a,c
where a.anid=c.cid
)
You will have null in the profession and salary columns from the first query and null in country and state columns in the second query
Try this
$query=(select a.name,a.age,b.country,b.state from a,b where a.aid=b.bid UNION select a.name,a.age,c.profession,c.salary from a,c where a.anid=c.cid)
by the way the fields in both select must be the same datatype
As I understood it a union was to do the same query on two different tables. If you get a result from the first half of the union you will not get the results from the second half.
Basic property of UNION is
Selected columns listed in
corresponding positions of each SELECT
statement should have the same data
type. (For example, the first column
selected by the first statement should
have the same type as the first column
selected by the other statements.)
If the data types of corresponding
SELECT columns do not match, the types
and lengths of the columns in the
UNION result take into account the
values retrieved by all of the SELECT
statements. For example, consider the
following:
I have a "boolean" column in one of my tables (value is either 0 or 1).
I need to get two counts: The number of rows that have the boolean set to 0 and the number of rows that have it set to 1. Currently I have two queries: One to count the 1's and the other to count the 0's.
Is MySQL traversing the entire table when counting rows with a WHERE condition? I'm wondering if there's a single query that would allow two counters based on different conditions?
Or is there a way to get the total count along side the WHERE conditioned count? This would be enough as I'd only have to subtract one count from the other (due to the boolean nature of the column). There are no NULL values.
Thanks.
You could group your records by your boolean column and get count for each group.
SELECT bool_column, COUNT(bool_column) FROM your_table
WHERE your_conditions
GROUP BY bool_column
This will obviously work not only for bool columns but also with other data types if you need that.
Try this one:
SELECT
SUM(your_field) as positive_count,
SUM(IF(your_field, 0, 1)) as negative_count
FROM thetable
If they are all either 0 or 1 and you dont mind 2 rows as result you can group by that field and do a count like so:
select field, count(field)
from table
group by field
A simple group clause should do the trick :
SELECT boolField, COUNT(boolField)
FROM myTable
GROUP BY boolField