I am having trouble with my sql query (Select distinct didnt work).
My sql is :
select distinct
count(T2.Column1)
from Table1 t2
where T2.Column1='2017-05-210'
The actual Column 1 data only have 3 data,
But the output is 12
Nb :
- Column1 data is having 1 to Many situation with Column2,
Here are the actual data:
Column 1 Column 2
1 A
1 B
1 C
1 D
2 A
2 B
2 C
2 D
3 A
3 B
3 C
3 D
Can anyone help me?
Really appreciate for your attention.
Thanks!
You want to count distinct values, so do count(distinct ):
select count(distinct T2.Column1)
from Table1 t2
where T2.Column1='2017-05-210'
(However, your sample data and the query's data/columns do not match.)
Your sample data, result and query do not match.
However, what your query does is:
Find all records with a column1 = '2017-05-210'.
Count all of these records where column1 is not null (which is true for all these records, as column1 = '2017-05-210').
This results in one number (one row, one column). But you additionally say with DISTINCT that you want to remove any duplicates from your result rows. With one row only there can be no duplicates, so the function is superfluous here.
So think about what you want to count really. You count distinct values (i.e. count ignoring duplicates) with COUNT(DISTINCT column), but COUNT(DISTINCT column1) would return 1 of course, because you are only looking for one value which is '2017-05-210' (or zero in case there is no record matching this value).
Related
sql. There is a table T with an id field (optionally unique) that contains N rows. How many rows can the following SQL query return?
select * from T
inner join (
select count(*) as cnt from T
union all select count(*) as cnt from T
) as TA on TA.cnt = T.id
inner join (
select count(*) as cnt from T
union select count(*) as cnt from T
) as TB on TB.cnt = T.id;
I have some options:
only N rows
from 0 to N rows
from 2N to 4N rows
or can you name some other options ?
This query returns either no rows or 2 rows (with all three columns having the same value).
Rationale:
The union all subquery (aliased TA) returns 2 rows, each containing the same value, that is the count of records in T.
The union subquery deduplicates its result and returns a single record, also containing the row count of the table
What happens next depends whether there is a record in the table whose id is equal to that number.
If such record exists, then the query returns 2 rows: one for each row generated by the union all subquery.
If there is no such record, the query return no rows at all.
So assuming this dataset:
id
--
1
2
There are two rows in the table, and id 2 exists, so the query gives you two rows with that id.
If we change this to:
id
--
1
2
3
5
There are four rows but not id 4. The query comes up empty.
0 rows if T.Id does not contain the value 2.
2 rows id T.Id contains the value 2
I want to select a data in where clause. Say that I have $values: 1,2,3,4
And then I want to select rows from table in that values.
SELECT `date` from another_table where id in (1,2,3,4)
If another_table only have rows with id 1,2 and 3 only, it mean that the id of 4 is not exist. I want the id of 4 is still selected with return of null or nol or NEVER.
another_table
-------+-------------+
| id | date |
----------------------
1 Yesterday
2 Today
3 Tomorow
5 Today
The expected result would be
-------+-------------+
| id | date |
----------------------
1 Yesterday
2 Today
3 Tomorow
4 Never
How to do this?
Thanks in advance
As one option use an inline view as a rowsource, and perform an outer join operation. We can use an IF expression to check whether a matching row was returned from another_table, we know the id value will not be NULL if there was a matching row, the join predicate (in the ON clause) guarantees us that.)
As an example:
SELECT n.id
, IF(a.id IS NULL,'Never',a.date) AS `date`
FROM ( SELECT 1 AS id
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
) n
LEFT
JOIN another_table a
ON a.id = n.id
ORDER BY n.id
The inline view query gets executed, and the results are materialized into a temporary table (MySQL calls it a derived table). When the outer query runs, n is effectively a table containing 4 rows.
Obviously, if the list of id values has to change, you'd need to change the view definition. The SQL text for the inline view can be generated dynamically from an array in a programming language from an array.
For a large number of values, the inline view becomes unwieldy, and you'd get better performance from a table, rather than the view.
I have a mySQL dataset that looks like this:
ID PARENT_ID VALUE
1 100 This comment should be approved
2 100 Y
3 101 Another approved comment
4 101 Y
5 102 This comment is not approved
6 102 N
I need to construct an SQL query to select the rows that have a matching parent_id and corresponding value of Y (but ignore the rows with single letters as a value in the result) to result in:
ID PARENT_ID VALUE
1 100 This comment should be approved
3 101 Another approved comment
My idea is to use GROUP BY to combine the columns, but I can't work out how to select based on the Y/N values.
There is possibly a solution here How do I select a row based on a priority value in another row? but I don't think it is asking quite the same question.
Any ideas?
Although you can express this as an aggregation, you can express this using exists:
select d.*
from dataset d
where d.value <> 'Y' and
exists (select 1
from dataset d2
where d2.parent_id = d.parent_id and d2.value = 'Y'
);
This version is probably more efficient.
First, if you possibly can, change your table schema. Your table is storing two kinds of data in the same field (yes no flags and comments). This breaks normality and will haunt you later.
But if its not your table to change, you will need to self join. Try this.
SELECT a.id, a.parent_Id, a.value
FROM table a inner join table b
ON a.parent_id =b.parent_id
WHERE a.value <> 'Y' and b.value ='Y'
I hope you can help me with this one. I've been looking for ways to set up a MySQL query that selects rows based on the number of times a certain value occurs, but have had no luck so far. I'm pretty sure i need to use count(*) somewhere, but i can only found how to count all values or all distinct values, instead of counting all occurences.
I have a table as such:
info setid
-- --
A 1
B 1
C 2
D 1
E 2
F 3
G 1
H 3
What i need is a query that will select all the lines where a setid occurs a certain number (x) of times.
So using x=2 should give me
C 2
E 2
F 3
H 3
because both setIds 2 and 3 each occur two times. Using x=1 or x = 3 should not give any results, and choosing x=4 should give me
A 1
B 1
D 1
G 1
Because only setid 1 occurs 4 times.
I hope you guys can help me. At this point i've been looking for the answer for so long that i'm not even sure this can be done in MySQL anymore. :)
select * from mytable
where setid in (
select setid from mytable
group by setid
having count(*) = 2
)
you can specify the # of times a setid needs to occur in the table in the having count(*) part of the subquery
Consider the following statement that uses an uncorrelated subquery:
SELECT ... FROM t1 WHERE t1.a IN (SELECT b FROM t2);
The optimizer rewrites the statement to a correlated subquery:
SELECT ... FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t2.b = t1.a);
If the inner and outer queries return M and N rows, respectively, the execution time becomes on the order of O(M×N), rather than O(M+N) as it would be for an uncorrelated subquery.
But this time the subquery in Fuzzy Tree's solution is complety superfluous:
SELECT
set_id,
GROUP_CONCAT(info ORDER BY info) infos
COUNT(*) total
FROM
tablename
GROUP_BY set_id
HAVING COUNT(*) = 2
I have two MySQL tables. What I am trying to do is to export the information where Value 1 is 1 less than Value 2 AND where ID_1 does not have its Value 1 and Value 2 equal.
Note:
Fields Value 1 and 2 are just integers.
Each distinct ID_A has the same Value_2
If there are two Value_1s that are one less than Value_2, look to Value_3 and select one that is higher
The reason why I have two tables here is because I am going to output information from both tables
We can write a script for this, but I need to do this in a single command for bonus points (which my instructor declared is possible)... I haven't even started a script for this, as I don't really know how to do that...
tableA looks like this:
ID_1 ID_2
A A
A B
B A
B B
C A
C B
C C
tableB looks like this:
ID_1 ID_2 Value_1 Value_2 Value_3
A A 2 3 NULL
A B 3 3 NULL
B A 4 5 NULL
B B 7 5 NULL
C A 7 8 98
C B 3 8 NULL
C C 7 8 56
The query should return this:
ID_1 ID_2
B A
C A
Here is what I have so far... And it keeps returning no hits, which is making me confused. I believe it is the AND clause after the first WHERE statement where I need to fix
SELECT CONCAT(...)
INTO OUTFILE '/tmp/outfile.tab'
FIELDS TERMINATED BY '\t'
ESCAPED BY ''
FROM tableA
INNER
JOIN tableB
ON tableA.ID_1 = tableB.ID_1
AND tableA.ID_2 = tableB.ID_2
WHERE tableB.Value_1 - 1 = tableB.Value_2
AND tableA.ID_1 !=
( SELECT DISTINCT
ID_1
FROM tableB
WHERE ID_1 = tableA.ID_1
AND Value_1 = Value_2
)
;
One final note: we issue all commands through putty, in which we can access MySQL
To be honest, I still don't understand exactly what you're trying to do, but I can explain why your query is returning no rows.
Look at this clause:
AND tableA.ID_1 !=
( SELECT DISTINCT
ID_1
FROM tableB
WHERE ID_1 = tableA.ID_1
AND Value_1 = Value_2
)
The subquery will necessarily always return either tableA.ID_1 or NULL. (Do you see why?) So the comparison is never "true"; it's always either "false" (because tableA.ID_1 != tableA.ID_1 is necessarily "false") or "null/indeterminate" (because tableA.ID_1 != NULL is "null/indeterminate"). Therefore, this clause filters out all results from your query — regardless of what the rest of your query might say.
I am not 100% sure of the question, but if I get it right, the first row of tableB (Line 25 in http://imgur.com/a/r3Qy5#1) should NOT be selected, because ID_1=A has Value_1=3 in the second row (Line 26 in http://imgur.com/a/r3Qy5#1), which is the same as Value_1 of the first row (Line 25 in http://imgur.com/a/r3Qy5#1).
So you could start with something like
SELECT .... FROM
tableA NATURAL JOIN tableB
WHERE Value_1=Value_2-1
AND Value_2 NOT IN (SELECT tb.Value_1 from tableB AS tb WHERE tb.ID_1=tableB.ID_1)
which fullfills requirements #1 and #2. For requirement #3 (if there are two rows for an ID_1, chose the one with the highest Value_3), we need to sort that on Value_3 and wrap it in a superquery for grouping:
SELECT .... FROM (
SELECT * FROM
tableA NATURAL JOIN tableB
WHERE Value_1=Value_2-1
AND Value_2 NOT IN (SELECT tb.Value_1 from tableB AS tb WHERE tb.ID_1=tableB.ID_1)
ORDER BY Value_3 DESC
) AS innerview
GROUP BY Value_1,Value_2
which gives the correct answer for the test data in your example.
You'll FIRST have to apply a test for your "Value_3" criteria grouped by the respective "ID_1" classification and Value1, value2. By applying the WHERE clause here, you are getting your final set of records INCLUSIVE of what WOULD be the highest value 3 entry in its result set. Now, that gets joined again to tableB AGAIN, but matching the qualifying entries. Since the COALESCE() will change any NULL value to 0 in the first result set, the JOIN clause must also match that. As in the case for the "A" and "B" groups where no Value_3 was applied, yet in the "C" group, it WILL have a valid value and pre-result in the entry with the max value of 98. That said, when re-joined back to instance "tb2" for TableB a second time will get the proper ID_2 of "A" for that set.
select
MaxQualified.ID_1,
tb2.ID_2,
MaxQualified.Value_1,
MaxQualified.Value_2,
tb2.Value_3
from
( select
tb.ID_1,
tb.Value_1,
tb.Value_2,
MAX( COALESCE( tb.Value_3, 0 ) ) as HighestVal3
from
TableB tb
where
tb.Value_1 +1 = tb.Value_2
group by
tb.ID_1,
tb.Value_1,
tb.Value_2 ) MaxQualified
JOIN TableB tb2
on MaxQualified.ID_1 = tb2.ID_1
AND MaxQualified.Value_1 = tb2.Value_1
AND MaxQualified.Value_2 = tb2.Value_2
AND MaxQualified.HighestVal3 = COALESCE( tb2.Value_3, 0 )
Now, that being said, and this is homework, this COULD fail or give multiple answers if you had multiple ID1, Value1, Value2, Value3 entries. It would return all "ID2" instances of the exact same common criteria. You would have to do even one more level nested to remove that level of distinction.
Your answer should ALSO return "A", "A", 2, 3