Mysql GROUP BY similar fields - mysql

Suppose I have this table with customer orders:
orderid Name Email Address_1 Address_2 City* Zip*
---------------------------------------------------------------------------
1 James j#j.com 12 Foo St Fooville 1001
2 Alice a#a.com 92 Bla Road Sville 3933
3 James j#j.c0m 12 Foo Street Fooville 1001
4 james king j#j.com 12 Foo St Fooville 1001
5 Anth ann#h.com 12 Foo Street Stacker 2932
6 James j#j.com 12 American St GiftCity 0283
To save postage costs (for us), it would be ideal if we could send multiple orders going to the same person, to the same address in one print slip. For this, I need a unique record for id 1, 3, 4.
The City and Zip codes cannot be entered by the user (selected from a drop down).
Ideally, I would like the following to be returned by my query:
orderid Name Email Address_1 Address_2 City* Zip* Count
---------------------------------------------------------------------------
1 James j#j.com 12 Foo St Fooville 1001 3
2 Alice a#a.com 92 Bla Road Sville 3933 1
5 Anth ann#h.com 12 Foo Street Stacker 2932 1
Essentially, the SQL algorithm is doing a group by on similar on the following columns: Name, Email, concat(Address_1 and Address_2).
Any advice and solutions would be highly appreciated.
If there is a way to do a
GROUP BY similar((concat(name,email,address_1)
(really sorry about the hopeless pseudo-code.. just trying to get my thoughts across).

Well instead of discussion here is a query modify according to your requirements
select
orderid ,
name ,
email ,
address_1 ,
address_2 ,
city ,
zip ,
count(orderid)
from test
group by name
order by orderid
Brings out this
Name Email Address_1 Address_2 City Zip Count
1 James j#j.com 12 Foo St Fooville 1001 3
2 Alice a#a.com 92 Bla Road Sville 3933 1
4 James King j#j.com 12 Foo St Fooville 1001 1
5 Anth ann#h.com 12 Foo St Stacker 2932 1

Related

I am trying to return combined rows in the same table based on a key in a second table

I probably haven't explained this very well in the title but I have two tables. Here is a simple version.
channel_data
entry_id channel_id first_name last_name model other_fields
1 4 John Smith
2 4 Jane Doe
3 4 Bill Evans
4 15 235
5 15 765
6 15 543
7 15 723
8 15 354
9 15 976
10 1 xxx
11 2 yyy
12 3 123
channel_titles
entry_id author_id channel_id
1 101 4
2 102 4
3 103 4
4 101 15
5 101 15
6 101 15
7 102 15
8 102 15
9 103 15
10 101 1
11 102 2
12 103 3
I am not able to re-model the data unfortunately.
I need to list all the rows with a channel_id 15 from channel_data and beside them the first_name and last_name which has the same author_id from channel_titles.
What I want to return is this:
Model First Name Last Name
---------------------------------
235 John Smith
765 John Smith
543 John Smith
723 Jane Doe
354 Jane Doe
976 Bill Evans
If Model was in one table and Names were in another this would be much simpler but I'm not sure how to go about this when they are in the same table.
========================================
Edited to clarify.
I need to get each model with a channel_id 15 from channel_data
For each model I need to look up the entry_id in channel_titles to find the author_id
I need to find the row with that author_id AND channel_id 4 in channel titles (each row with channel_id 4 has a unique author_id).
I need to take the entry_id of this row back to channel_data and get the first_name and last_name to go with the model.
I am well aware that the data is not structured well but that is what I have to work with. I am trying to accomplish a very small task in a much larger system, remodelling the data is not an option at this point.
I think sub-queries might be what I am looking for but this is not my area at all usually.
Ok, that is convoluted. However, based on your description, this query should give you the results you want. The WHERE and JOIN descriptions follow the logic you have described in your question.
SELECT cd1.model, cd2.first_name, cd2.last_name
FROM channel_data cd1
JOIN channel_titles ct1 ON ct1.entry_id = cd1.entry_id
JOIN channel_titles ct2 ON ct2.channel_id = 4 AND ct2.author_id = ct1.author_id
JOIN channel_data cd2 ON cd2.entry_id = ct2.entry_id
WHERE cd1.channel_id = 15
ORDER BY cd1.entry_id
Output:
model first_name last_name
235 John Smith
765 John Smith
543 John Smith
723 Jane Doe
354 Jane Doe
976 Bill Evans
Demo on SQLFiddle

How to perform these joins with MySQL?

Having these tables:
clients
-------------------
id
name
town
companies
------------------
id
name
credits
------------------
clients_id
companies_id
credit
Example:
clients
-------------
1 john doe London
2 jane smith Paris
companies
-------------
1 mycompany1
2 mycompany2
credits
-------------
1 1 5000
1 2 3250
2 2 4500
How can I list all the clients including an additional column for each credit she has in a company? I also need to alias each of these columns in this fashion: "credit_"
Something like:
id name town credit_1 credit_2
1 john doe London 5000 3250
2 jane smith Paris NULL 4500
I'm not sure if doing two LEFT JOINS to credits would work.

prediction on rowwise data or progressive data

I am working on employee attrition analysis with a table having rowwise data for a (employee like Id, name, Date_Join Date_Relieving Dept Role etc)
eID eName Joining Releiving Dept Married Experience
123 John Doe 10Oct15 12Oct16 HR No 12
234 Jen Doee 01jan16 -NA- HR No 11 (ie she is available)
I can run regression on this data to find the beta coefficient
eID eName Joining Releiving Dept Married Experience
123 John Doe 10Oct15 12Oct16 HR No 12
234 Jen Doee 01jan16 -NA- HR No 11
But I've seen other approach too.. where employee have multiple entries depending on their difference between joining date and current month or relieving month(say Employee A joined in Jan and Left in Dec so he'll have 12 entries updating corresponding columns like experience and marriage etc)
eID eName Dept Married Experience
123 John Doe HR No 0
123 John Doe HR No 1
123 John Doe HR Yes 2
123 John Doe HR Yes 3
can someone tell what differentiate two approaches.. and what is the outcome of this second approach.

In SQL select and count all entries where with same value in column

I have a table like in an mysql-database.
id section number name
1 A 1234 fred
2 B 5678 mo
3 B 1234 fred
4 C 8901 lou
5 A 8901 lou
6 A 2345 lee
7 B 2345 lee
8 C 2345 lee
9 A 6789 paul
10 B 1234 fred
This is my table and i need to get all numbers is in more then one section with the name of the section. like this
id section number name
1 A 1234 fred
3 B 1234 fred
Fred is in section A and B.
In my solution i get this
id section number count name
1 A 1234 1 fred
3 B 1234 2 fred
6 A 2345 1 lee
7 B 2345 1 lee
8 C 2345 1 lee
2 B 5678 1 mo
9 A 6789 1 paul
4 C 8901 1 lou
5 A 8901 1 lou
in my way i try is sql select
SELECT id, section, number, count(number) AS count, name
FROM table
GROUP BY section, number
ORDER BY number
Is is the right way? How can i improve that for mor number columns, if have 3 numbercolumns
id section number1 number2 number3 name
Now i do this with 3 sql-statements

How does the NOT IN logical operator work to generate this output? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have the following tables and data: Screenshot of the data here
course:
course# ctitle units
--------- ------------------- -----
ACCT 201 Financial Account 3
CHEM 356 Organic Chemistry 4
HIST 101 US History 5
MINS 235 Database Design 4
MINS 301 Intro to Business IS 3
MINS 350 Systems Analysis 4
PHED 434 Advanced Gym 2
class:
class# course# sec# semyr
------ ---------- ----- -----
203 ACCT 201 03 F11
204 ACCT 201 04 F11
307 MINS 301 07 F11
418 MINS 235 04 F11
438 MINS 350 01 F11
624 PHED 434 02 F11
student:
sid sname major
--- ---------- ----------
1 Bob MINS
2 Mary POMG
3 Joe MGMT
4 Sue MKTG
5 Jim ACCT
class_student:
class sid grade
----- ---- -----
203 2 B
203 5 D
204 1 C
204 4 C
307 1 B
307 2 B
307 4 A
418 1 A
418 2 B
418 5 C
438 1 B
438 4 C
634 5 F
grade:
grade grade_pts
----- ---------
A 4
B 3
C 2
D 1
F 0
When I run the following query:
SELECT *
FROM STUDENT
WHERE SID NOT IN
( SELECT SID
FROM CLASS_STUDENT
WHERE GRADE IN ('A' , 'B')
)
ORDER BY SID;
I think Oracle would generate this output.
sid sname major
--- ----- -----
1 bob mins
4 sue mktg
5 jim acct
5 jim acct
5 jim acct
I would like to understand how NOT IN logical operator works. How does the NOT IN operator work in the above query to generate the output?
It returns students with grades worse than B.
NOT IN filters out what you define after that.
In words:
select all student but not the ones that have grades A or B
SELECT SID FROM CLASS_STUDENT WHERE GRADE IN ( 'A' , 'B' )
will select the sid of the students having A,B grades.
will result in a list of sid
SID
2
1
2
4
1
2
1
then
SELECT * FROM STUDENT
WHERE SID NOT IN ...
will result in :
SID sname Major
3 joe mgmt
5 jim acct
The subquery (SELECT SID FROM CLASS_STUDENT WHERE GRADE IN ( 'A' , 'B' )) selects the SIDs of all students that have an A or B grade in at least one class. When used with an IN operator, the list is implicitly deduplicated. It appears in your data that students 1, 2, and 4 all have an A or B in at least one class, so would be included in the result set of this subquery.
Then, the full query is simply selecting all rows from STUDENT that are not included in the list returned by the subquery. So I think you are getting two rows, with SIDs 3 and 5.
Your "expected result" makes little sense. There is no reason to expect multiple rows for the same student when your query is selecting all students then filtering some out.
What your query is doing is showing students that don't have an A or B grade in at least one class. I suspect that what you want is to show each student-class combination for which the grade is worse than a B (that seems consistent with your expected result). To do this, I would suggest driving the query off of the CLASS_STUDENT table, and joining to STUDENT to get the student information (and perhaps to CLASS and COURSE to get the name of the course, if desired).