stuck; SQL case statement with aggregate function - mysql

I am stuck on a problem and I am hoping that you guys can help.
I am running mySQL with XAMPP and PHP My Admin (PMA)
I have two tables:
Table A
A |B
1000000001 |100000001
1000000001 |100000002
1000000001 |100000003
1000000002 |100000004
1000000002 |100000005
1000000003 |100000006
Table B
C |D
1000000001|100000000000001
1000000002|100000000000002
1000000003|100000000000003
1000000004|100000000000004
1000000005|100000000000005
1000000006|100000000000006
I have joined the two tables to represent the following:
A |B/C |D
100000001|1000000001|100000000000001
100000001|1000000002|100000000000002
100000001|1000000003|100000000000003
100000002|1000000004|100000000000004
100000002|1000000005|100000000000005
100000003|1000000006|100000000000006
Notice the pattern that occurs in the first three data points.
Essentially I need help understanding how to write a case script That would return a unique A value and the Count of the D value per A value
The Return would be:
A |D_COUNT
100000001|3
100000001|2
100000003|1
Thank you!

SELECT A,
COUNT(DISTINCT D) AS count_d
FROM table_c
GROUP BY A;

The tables you give seems to be a bit of a mistake,the length of TableA.B is 9 and TableB.C is 10 ,ignore this,you may write your query string like this:
select A,count(A) as D_COUNT
from t_a,t_b
where t_a.b=t_b.c
group by t_a.A;
TableA ==> t_a
TableB ==> t_b

Try this query:
select A,count(A) as D_Count from tablename group by A

Related

SUM of difference in values

I need to query in MS Access the difference in value of a column to 8 and only if it is greater than 8.
So if I have a column of numbers 1-10, I want to query the sum of all the value's differences from 8. So the result of the query for the below column would be 3. (9-8)+(10-8)
SELECT Sum(([time1]-8)+([time2]-8)+([time3]-8)+([time4]-8)+([time5]-8)+([time6]-8)+([time7]-8)+([time8]-8)+([time9]-8)+([time10]-8)+([time11]-8)+([time12]-8)+([time13]-8)+([time14]-8)+([time15]-8)+([time16]-8)+([time17]-8)+([time18]-8)+([time19]-8)+([time20]-8)+([time21]-8)+([time22]-8)) AS Total
FROM tblTimeTracking
WHERE (((Month(([Day])))=Month(Now()))) AND ([time1]>8 AND[time2]>8 AND[time3]>8 AND[time4]>8 AND[time5]>8 AND[time6]>8 AND[time7]>8 AND[time8]>8 AND[time9]>8 AND[time10]>8 AND[time11]>8 AND[time12]>8 AND[time13]>8 AND[time14]>8 AND[time15]>8 AND[time16]>8 AND[time17]>8 AND[time18]>8 AND[time19]>8 AND[time20]>8 AND[time21]>8 AND[time22]) ;
Thanks,
How about:
SELECT Sum([Value]-8) As SumOfVal
FROM table
WHERE [Value]>8
Edit re complete change in original question.
It is not clear what you want
SELECT Sum(([time1]-8)+([time2]-8) ...
WHERE [time1]>8 And Time2>8 ...
Time1>8 will exclude nulls, but if that is not what you are doing, you will need to consider:
Nz([time1],0) + ...
Edit re comments
Something like:
SELECT Sum(times) FROM
(SELECT IIf(Time1>8,Time1-8,Time1) As times FROM Table
UNION ALL
SELECT IIf(Time2>8,Time2-8,Time2) As times FROM Table) As b
As b is an alias: Access SQL
UNION / UNION ALL: View a unified result from multiple queries with a union query

inner join returning only 1 row using like clause instead of two

I have the below sql, which if i take out the inner join to the table and hard code the values, i get 2 records. But when i use the inner join statement, i just get 1 record. I am aware that with MYSQL, the like clause, is not case sensitive. Here is the sql below. I dont know why it is only returning row.
SELECT
a.project_code as projectCode,
a.project_name as projectName,
a.project_creation_date as projectCreationDate,
a.project_end_date as projectEndDate,
a.project_status as projectStatus
from projects a
inner join tmp_rec_naren8 b
on a.project_name like concat("%",b.expertise_desc,"%")
OR a.project_description like concat("%",b.expertise_desc,"%") ;
If I change the above to:
select *
from projects
where project_name like '%java%'
OR project_description like '%java%';
I get 2 rows and not 1.
Table tmp_rec_naren8 has just one column expertise_desc and contains this data:
expertise_desc
--------------
XML
Python
DWH
Java
Table projects has many columns :.. But these below are the relevant ones
project_code sr_user_name project_name project_descriiption ..
-----------------------------------------------------------
1 naren5 POS C++, XML,Java
2 naren7 INV Networking
3 naren9 CCV Java, Unix
The first query returns 1 row:
project_code sr_user_name project_name project_descriiption ..
---------------------------------------------------------------
1 naren5 POS C++,XML,Java
The second query returns 2 rows
project_code sr_user_name project_name project_descriiption ..
-----------------------------------------------------------
1 naren5 POS C++, XML,Java
3 naren9 CCV Java, Unix
One explanation would be if the value in expertise_desc contained a trailing space, ie 'Java ' (not 'Java'). Then the concat value would be '%java %', not '%java%', making a difference.
If one of your project names ended with java, and the other had java within the name, only one would match using the join, but two would match with the non-join.
Can you try the following:
SELECT
a.project_code as projectCode,
a.project_name as projectName,
a.project_creation_date as projectCreationDate,
a.project_end_date as projectEndDate,
a.project_status as projectStatus
from projects a, tmp_rec_naren8 b
where a.project_name like concat("%",b.expertise_desc,"%")
OR a.project_description like concat("%",b.expertise_desc,"%") ;
Give it a try:
SELECT
a.project_code as projectCode,
a.project_name as projectName,
a.project_creation_date as projectCreationDate,
a.project_end_date as projectEndDate,
a.project_status as projectStatus
from projects,tmp_rec_naren8
where LOCATE(TRIM(tmp_rec_naren8.expertise_desc),projects.project_name) > 0
or
LOCATE(TRIM(tmp_rec_naren8.expertise_desc),projects.project_description) > 0

Join Two tables multiple times

I need result from two tables , where one is parent table and other is child table as well as parent table it self for sub level child entries.
if i do the sql query like:
SELECT cc.collection_id, cc.title, cc.type, cc.alias as forum_alias,
SUBSTRING(cc.description,1,200) as short_desc,
COUNT(b1.boardmessage_id) as total_threads,
COUNT(b2.boardmessage_id) as total_replies
FROM contentcollections cc
JOIN boardmessages b1 ON b1.parent_id = cc.collection_id
JOIN boardmessages b2 ON b2.collection_id = cc.collection_id
WHERE cc.type=1
AND cc.is_active=1
AND b1.parent_type='collection'
AND b1.is_active=1
AND b2.parent_type IN('message','reply','reply_on_reply')
GROUP BY cc.collection_id
ORDER BY cc.created DESC;
it gives me the wrong out put with same number of total threads and same number of total replies.How ever if i do something like this
SELECT cc.collection_id, cc.title,cc.type, cc.alias as forum_alias,
SUBSTRING(cc.description,1,200) as short_desc,
(SELECT COUNT(boardmessage_id)
FROM boardmessages
WHERE parent_type='collection'
AND collection_id=cc.collection_id
AND is_active=1) as total_threads,
(SELECT count(boardmessage_id)
FROM boardmessages
WHERE parent_type IN('message','reply','reply_on_reply')
AND collection_id=cc.collection_id AND is_active=1) as total_replies
FROM contentcollections cc
WHERE cc.type=? AND cc.is_active=?
ORDER BY cc.created DESC
It gives me the correct answer.
I suspect i am using sub queries in the second option so it may slow down the performance of the page rendering.
Please suggest me for the same.Any help or suggestion would be greatly appreciated.
Thanks
Replace:
COUNT(b1.boardmessage_id) as total_threads,
COUNT(b2.boardmessage_id) as total_replies
With:
COUNT(DISTINCT b1.boardmessage_id) as total_threads,
COUNT(DISTINCT b2.boardmessage_id) as total_replies
if you only want each row to count once, instead of the default, counting all combinations.
If you have 3 rows in b1 and 5 rows in b2, you get a total of 15 rows, and both counts return that there are 15 rows, with the distinct flag you get the answers 3 and 5 instead, as its 3 distinct values in b1, and 5 distinct values in b2.

mysql select update

Got this:
Table a
ID RelatedBs
1 NULL
2 NULL
Table b
AID ID
1 1
1 2
1 3
2 4
2 5
2 6
Need Table a to have a comma separated list as given in table b. And then table b will become obsolete:
Table a
ID RelatedBs
1 1,2,3
2 4,5,6
This does not rund through all records, but just ad one 'b' to 'table a'
UPDATE a, b
SET relatedbs = CONCAT(relatedbs,',',b.id)
WHERE a.id = b.aid
UPDATE: Thanks, 3 correct answers (marked oldest as answer)! GROUP_CONCAT is the one to use. No need to insert commas between the ids using relatedids = CONCAT(relatedids,',',next_id) that is done automatic by GROUP_CONCAT.
You'll have to use the mysql group_concat function in order to achieve this: http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_group-concat
Look into GROUP_CONCAT(expr)
mysql> SELECT student_name,
-> GROUP_CONCAT(DISTINCT test_score
-> ORDER BY test_score DESC SEPARATOR " ")
-> FROM student
-> GROUP BY student_name;
You can't do that in standard SQL. You could write a stored procedure to do that. I had a similar problem, but I was using PostgreSQL so I was able to resolve it by writing a custom aggregate function so that you can do queries like
select aid, concat(id)
from b group by
aid
Update: MySQL has a group_concat aggregate function so you can do something like
SELECT id,GROUP_CONCAT(client_id) FROM services WHERE id = 3 GROUP BY id
as outlined here.

Mysql multiple tables select

I've got a table, called for example, "node", from which I need to return values for as shown:
SELECT nid FROM node WHERE type = "book"
After I get a list of values let's say:
|**nid**|
|123|
|12451|
|562|
|536|
Then I need to take these values, and check another table, for rows where column 'path' has values as "node/123", "node/12451" (numbers the previous request returned) in one joined request. It all would be easier if collumn 'path' had simple numbers, without the 'node/'.
And then also count the number of identical i.e. 'node/123' returned.
End result would look like:
nid | path | count(path) | count(distinct path)
123 |node/123| 412 | 123
562 |node/562| 123 | 56
Works fine if done in multiple separated queries, but that won't do.
select a.nid from node a join othertable b
on b.path = concat("node/", a.nid) where type='book'
You can probably do something like the following (nid may require additional conversion to some string type):
SELECT *
FROM OtherTable
JOIN node ON path = CONCAT('node/', nid)
WHERE type = 'book'
Thank you all for your help. Basically, the problem was that I didn't know how to get nid and node/ together, but concat helped.
End result looks something like:
SELECT node.nid, accesslog.path, count(accesslog.hostname), count(distinct accesslog.hostname)
FROM `node`, `accesslog`
WHERE node.uid=1
AND node.type='raamat'
AND accesslog.path = CONCAT('node/', node.nid)
GROUP BY node.nid