I want to perform a mySQL query that returns all the results in a table but has an additional column that has values "selected" if they correspond to a separate query. For example
| name |
|------|
| a |
| b |
| c |
I want to be able to return the following when I do a query "select * from table where name = 'a';
| name | selected |
|------|----------|
| a | yes |
| b | |
| c | |
That is, I also want to know which ones where left out.
select *
, selected = case
when exists (
select *
from table2 t2
where t2.field = t1.field
and ...etc.
) then 1
else 0
end
from table t1
Where clause restricts your row set so you get only rows with name 'a'.
To get all of them either join the limited table back to itself or use IF without where:
SELECT *, IF( name='a', 'yes', '') AS selected
FROM table
The one that worked for me was:
select a.*
, name = case
when
a.name = 'a'
then 0
else 1
end
as selected
from points as a
Related
I have a table in a mysql 5.7 DB called "mytable" that is made like so:
--------------------
| title | flag |
|--------------------|
| first | 0 |
| first | 1 |
| second | 0 |
--------------------
From this table I need to select only the rows with flag = 0, and from those remove all the ones that has the same title of one with flag = 1. Ending up with a result like this:
--------------------
| title | flag |
|--------------------|
| second | 0 |
--------------------
How can i write my query? Thanks.
Just use a sub-query and combine it with MySQL's IN() function. The following will work:
SELECT title,
flag
FROM mytable
WHERE flag = 0
AND title NOT IN( SELECT title FROM mytable WHERE flag = 1 );
SQL Fiddle
Doing a LEFT OUTER JOIN
SELECT a.*
FROM mytable a
LEFT OUTER JOIN mytable b
ON a.title = b.title
AND b.flag = 1
WHERE a.flag = 0
AND b.flag IS NULL
Do the LEFT OUTER JOIN, then check for NULL in one of the joined columns to ensure that there is no matching record found.
i have a table like this
i want to get the row of each table that have min responsetime
i have tried this query :
select tablename,
index1,
index2,
min(responsetime)
from tableconf
group by tablename
order by responsetime asc
but it doesn't give what i want
the output that i want is
+------------------+------------------+--------+--------------+
| tablename | index1 | index2 | responsetime |
+------------------+------------------+--------+--------------+
| salesorderheader | TotalDue | NULL | 6.1555 |
| salesterritory | Name | NULL | 11.66667 |
| store | BusinessEntityId | Name | 3.6222 |
| previous | previous | NULL | 5.03333 |
| NONE | NONE | NULL | 5.6 |
+------------------+------------------+--------+--------------+
what query i should use for get the output that i want
Select the minimum date per table name. Use an IN clause on these to get the rows:
select *
from tableconf
where (tablename, responsetime) in
(
select tablename, min(responsetime)
from tableconf
group by tablename
);
(Edited from previous answer)
I don't know if all SQL syntax accept a comma separated where parameter. Another option building off of the highest voted answer right now utilizes a join:
select *
from tableconf t
inner join (
select tablename, min(responsetime) min_rt
from tableconf t2
group by tablename
) t3 on t.tablename = t2.tablename and t.responsetime = t2.min_rt
I have two(2) tables and I'm trying to count all records from Table1 and Table1_delta were pagename from Table1_delta is not yet listed into Table1. Incase pagename from Table1_delta is listed to Table1, status must be 1 so that it will be included in count result.
Sample table structure:
Table1
+-----------+--------+
| pagename | status |
+-----------+--------+
| pagename1 | 2 |
| pagename2 | 1 |
+-----------+--------+
Table1_delta
+-----------+
| pagename |
+-----------+
| pagename1 |
| pagename2 |
| pagename3 |
| pagename4 |
+-----------+
The table sample should return "3".
pagename3 and pagename4 is not listed in Table1(that returns 2) and pagename2 from Table1 has an status = 1(that returns 1). In total there are 3 pagenames from Table1_delta that are not listed in Table1 and record from Table1 where status = 1. I'm wondering on how will be the query of this? I'm using MySQL v5.6.17. Thanks!
Here is an alternative solution using joins:
SELECT COUNT(*)
FROM Table1_delta t1 LEFT JOIN Table1 t2
ON t1.pagename = t2.pagename
WHERE t2.status IS NULL OR t2.status = 1
Here is what the temporary table from the above query looks like:
+-----------+--------+
| pagename | status |
+-----------+--------+
| pagename1 | 2 | # this row is NOT counted
| pagename2 | 1 | # +1 this row has status = 1 and is counted
| pagename3 | null | # +1 this row has status = null and is counted
| pagename4 | null | # +1 this row is also null and is counted
+-----------+--------+
Check out the link below for a running demo.
SQLFiddle
Try using joins
Select count(Table1_delta.pagename) from Table1_delta
INNER JOIN Table1 ON
Table1_delta.pagename != Table1 .pagename
AND Table1.status != 1
If I've understood correctly:
SELECT COUNT(*) FROM Table1_Delta
WHERE pagename NOT IN
(SELECT pagename FROM Table1 WHERE status = 1)
Update
As requested in the comments, here's what this query does:
First, the subquery: SELECT pagename FROM Table1 WHERE status = 1, retrieves the pagename field from those Table1 records where status is 1.
So in the example case, it'll return a single row, containing pagename2.
Then the main query counts all the records in Table1_Delta (SELECT COUNT(*) FROM Table1_Delta) whose Pagename does not contain (WHERE Pagename NOT IN (<subquery>)) those values returned from the subquery.
So this would match 3 entries (pagename1, pagename3, pagename4), and that's the count you get
Historically, using sub-queries is considered slower than using joins, but frankly, RDBMS's have come a long way optimizing queries, and for simple cases like this, it would be "probably" (I haven't measured) faster. It actually depends on the real case and DB... but the SQL code is much more self-explanatory than joins IMO. Your mileage may vary.
I have these two tables, say faq_categories and faq_category_relations. First I do a query in tabel faq_category_relations, like
SELECT category_id
FROM faq_category_relations
WHERE faq_id = 2;
And the result_a is
--------------
|category_id |
--------------
| 2 |
--------------
| 3 |
--------------
Then I want to query table faq_categories and add one column checked, the value of which is set according to result_a(that is, if faq_categories.id is one of the values in result_a, set the checked to be true, else false), to the query results.
Till now I only come up with:
SELECT *, IF((faq_categories.id is one of result_a), 'true', 'false') AS checked
FROM faq_categories
And have no idea how to continue..
I know I can do that trick in PHP after retrieving the query data, but there must be some simple way to directly return the query results I needed.
EIDT:
The result should come out like this:
---------------------------
|category_id | checked |
---------------------------
| 1 | false |
---------------------------
| 2 | true |
---------------------------
| 3 | true |
---------------------------
| 4 | false |
---------------------------
| 5 | false |
---------------------------
Assuming there are no duplicates in faq_category_relations, then you can do this with a left outr join and a case expression:
SELECT c.*,
(case when cr.category_id is not null then 'true' else 'false' end) as checked
FROM faq_categories c left outer join
faq_category_relations cr
on c.category_id = cr.category_id and
cr.faq_id = 2;
I am also assuming that you just need the value in a query and not as a new column in the table.
The simplest way is:
select c.*, cr.category_id is not null checked
from faq_categories c
left join faq_category_relations cr
on c.category_id = cr.category_id
where cr.faq_id = 2
This works because with left joins, the values in the joined columns will be null if there's no join, so testing for not null will tell you if the category was listed in the other table.
If you want you can move the condition on faq_id into the join condition, which can be done by changing where to and in the above query.
I have a table with the format:
Id | Loc |
-------|-----|
789-A | 4 |
123 | 1 |
123-BZ | 1 |
123-CG | 2 |
456 | 2 |
456 | 3 |
789 | 4 |
I want to exclude certain rows from the result of query based on whether a duplicate exists. In this case, though, the definition of a duplicate row is pretty complex:
If any row returned by the query (let's refer to this hypothetical row as ThisRow) has a counterpart row also contained within the query results where Loc is identical to ThisRow.Loc AND Id is of the form <ThisRow.Id>-<an alphanumeric suffix> then ThisRow should be considered a duplicate and excluded from the query results.
For example, using the table above, SELECT * FROM table should return the results set below:
Id | Loc |
-------|-----|
789-A | 4 |
123-BZ | 1 |
123-CG | 2 |
456 | 2 |
456 | 3 |
I understand how to write the string matching conditional:
ThisRow.Id REGEXP '^PossibleDuplicateRow.Id-[A-Za-z0-9]*'
and the straight comparison of Loc:
ThisRow.Loc = PossibleDuplicateRow.Loc
What I don't understand is how to form these conditionals into a (self-referential?) query.
Here's one way:
SELECT *
FROM myTable t1
WHERE NOT EXISTS
(
SELECT 1
FROM myTable t2
WHERE t2.Loc = t1.Loc
AND t2.Id LIKE CONCAT(t1.Id, '-%')
)
SQL Fiddle example
Or, the same query using an anti-join (which should be a little faster):
SELECT *
FROM myTable t1
LEFT OUTER JOIN myTable t2
ON t2.Loc = t1.Loc
AND t2.Id LIKE CONCAT(t1.Id, '-%')
WHERE t2.Id IS NULL
SQL Fiddle example
In the example data you give, there are no examples of duplicate locs not being on duplicate rows. For example, you don't have a row "123-AZ, 1", where the prefix row "123, 1" would conflict with two rows.
If this is a real characteristic of the data, then you can eliminate dups without a self join, by using aggregation:
select max(id), loc
from t
group by (case when locate(id, '-') = 0 then id
else left(id, locate(id, '-') - 1)
end), loc
I offer this because an aggregation should be much faster than a non-equijoin.