Count grouped records by day - sql

I am having some minor trouble with creating a query in Access using SQL. Any help would be greatly appreciated.
I am trying to create a query that looks like this
The database looks like this (I had to recreate it with generic names)
LOG
dispatcher tech zone serviceorder casesummary resolution date_
John Doe Trump MZ 13458215 MZ/ description Replaced Printer 8/1/2015
John Doe Clinton Core 45821654 Core/ description Added Paper 8/1/2015
John Doe Smith WA 12458254 WA/ description WOA 8/1/2015
John Doe Smith WA 15465224 WA/ description Replaced Printer 8/2/2015
John Doe Williams WB 15468521 WB/ description Replaced Scangun 8/2/2015
John Doe Jones WFF 48593258 WFF/ description Replaced Scangun 8/3/2015
John Doe Jones WFF 15487528 WFF/ description Replaced printer 8/4/2015
Bob Dole Jones WA 65328451 WA/ description WOA 8/4/2015
Bob Dole Williams WB 48521596 WB/ description WOA 8/5/2015
Bob Dole Trump WC 34852369 WC/ description WOA 8/5/2015
Bob Dole Trump WC 63214789 WC/ description Replaced Printer 8/5/2015
Bob Dole Williams WB 52369852 WB/ description Added Paper 8/6/2015
Bob Dole Johnson WE 25896325 WE/ description WOA 8/6/2015
Jack Hill Jones WC 78521478 WC/ description Replaced Printer 8/6/2015
Jack Hill Jones WC 52585258 WC/ description Replaced Scangun 8/7/2015
Jack Hill Johnson WD 12457898 WD/ description Replaced Scangun 8/8/2015
Jack Hill Clinton Core 45698523 Core/ description Replaced printer 8/8/2015
Jack Hill Smith WA 32589654 WA/ description WOA 8/8/2015
The current code I have is this
SELECT DISTINCT Format(Log.Date_,"ddd") AS [Day], LOG.Date_,
(select COUNT(*) FROM LOG
Where Zone_of_call = "WFF") AS WA
FROM LOG
WHERE (((LOG.Date_) >= [Start Date] And (LOG.Date_) <= [End Date]))
ORDER BY LOG.Date_;
Where the database is LOG. I skipped techs and dispatches and jumped to the Columns for the daily count of each case by zone.

Related

Presenting Data uniformly between two different table presentations with SQL

Hello Everyone I have a problem…
Table 1 (sorted) is laid out like this:
User ID Producer ID Company Number
JWROSE 23401 234
KXPEAR 23903 239
LMWEEM 27902 279
KJMORS 18301 183
Table 2 (unsorted) looks like this:
Client Name City Company Number
Rajat Smith London JWROSE
Robert Singh Cleveland KXPEAR
Alberto Johnson New York City LMWEEM
Betty Lee Dallas KJMORS
Chase Galvez Houston 23401
Hassan Jackson Seattle 23903
Tooti Fruity Boise 27902
Joe Trump Tokyo 18301
Donald Biden Cairo 234
Mike Harris Rome 239
Kamala Pence Moscow 279
Adolf Washington Bangkok 183
Now… Table 1 has all of the User IDs and Producer IDs properly rowed with the Company Number.
I want to pull all the data and correctly sorted….
Client Name City User ID Producer ID Company Number
Rajat Smith London JWROSE 23401 234
Robert Singh Cleveland KXPEAR 23903 239
Alberto Johnson New York City LMWEEM 27902 279
Betty Lee Dallas KJMORS 18301 183
Chase Galvez Houston JWROSE 23401 234
Hassan Jackson Seattle KXPEAR 23903 239
Tooti Fruity Boise LMWEEM 27902 279
Joe Trump Tokyo KJMORS 18301 183
Donald Biden Cairo JWROSE 23401 234
Mike Harris Rome KXPEAR 23903 239
Kamala Pence Moscow LMWEEM 27902 279
Adolf Washington Bangkok KJMORS 18301 183
Query:
Select
b.client_name,
b.city.,
a.user_id,
a.producer_id,
a.company_number
From Table 1 A
Left Join Table 2 B On a.company….
And this is where I don’t know what do to….because both tables have all the same variables, but Company Number in Table 2 is mixed with User IDs and Producer IDs... however we know what company Number those ID's are associated to.
As I mention in the comments, and others do, the real problem is your design. "The fact that UserID is clearly a varchar, while the other 2 columns are an int really does not make this any better", and makes this not simple (and certainly not SARGable).
To get the data in the correct order, as well, you need a column to order it on which the data lacks. I have therefore added a pseudo column, MissingIDColumn, to represent this missing column you need to add to your data; which you can do when you fix the design:
SELECT T2.ClientName,
T2.City,
T1.UserID,
T1.ProducerID,
T1.CompanyNumber
FROM (VALUES('JWROSE',23401,234),
('KXPEAR',23903,239),
('LMWEEM',27902,279),
('KJMORS',18301,183))T1(UserID,ProducerID,CompanyNumber)
JOIN (VALUES(1,'Rajat Smith ','London ','JWROSE'),
(2,'Robert Singh ','Cleveland ','KXPEAR'),
(3,'Alberto Johnson ','New York City','LMWEEM'),
(4,'Betty Lee ','Dallas ','KJMORS'),
(5,'Chase Galvez ','Houston ','23401'),
(6,'Hassan Jackson ','Seattle ','23903'),
(7,'Tooti Fruity ','Boise ','27902'),
(8,'Joe Trump ','Tokyo ','18301'),
(9,'Donald Biden ','Cairo ','234'),
(10,'Mike Harris ','Rome ','239'),
(11,'Kamala Pence ','Moscow ','279'),
(12,'Adolf Washington','Bangkok ','183'))T2(MissingIDColumn,ClientName,City,CompanyNumber) ON T2.CompanyNumber IN (T1.UserID,CONVERT(varchar(6),T1.ProducerID),CONVERT(varchar(6),T1.CompanyNumber))
ORDER BY MissingIDColumn;

SQL query: selecting only NULL values from a group?

I'm working with a data table that looks something like this:
Names City Date Color Shape
John Smith Baltimore 8/1/2015 Blue
John Smith Baltimore 8/1/2015 Green
John Smith Baltimore 8/1/2015 Rectangle
John Smith Baltimore 8/1/2015
John Smith Baltimore 8/1/2015 Square
John Smith Baltimore 8/1/2015
Rob Johnson Baltimore 8/1/2015
Rob Johnson Baltimore 8/1/2015
Rob Johnson Baltimore 8/1/2015
Rob Johnson Baltimore 8/1/2015
Rob Johnson Baltimore 8/1/2015
Greg Jackson Philadelphia 8/1/2015
Greg Jackson Philadelphia 8/1/2015
Greg Jackson Philadelphia 8/1/2015
Greg Jackson Philadelphia 8/1/2015 Circle
Greg Jackson Philadelphia 8/1/2015
Tom Green Philadelphia 8/1/2015
Tom Green Philadelphia 8/1/2015
Tom Green Philadelphia 8/1/2015 Red
Tom Green Philadelphia 8/1/2015
Tom Green Philadelphia 8/1/2015
My goal with the query is to SELECT all five of the data types present, but to isolate those values in the Names field that have NULL values in the Color and Shape fields. I'm writing this SQL in MS Access. My query so far looks like this:
SELECT [Names], [City], [Date], [Color], [Shape]
FROM [databasename]
WHERE
(
([Color] IS NULL)
AND
([Shape] IS NULL)
);
From the sample data table, I'd like for the results to only include Rob Johnson, since all rows associated with that Name entry have NULL values for the Color and Shape fields. However, with this query, I'm getting all of the other names as well, with the specific rows with NULL values in the Color and Shape fields being returned.
So, the expected output would look like this:
Names City Date Color Shape
Rob Johnson Baltimore 8/1/2015
I suspect that I need to use a GROUP operator here, but I'm not quite sure how to do that. Any ideas?
I think you want this:
SELECT
DISTINCT [Names], [City], [Date], [Color], [Shape]
FROM [table]
WHERE [Names] NOT IN (
SELECT [Names] FROM [table] WHERE ([Color] IS NOT NULL) OR
([Shape] IS NOT NULL)
);
It can be done in other ways, but this should be close to your original query.
You can use an aggregate and inner join:
SELECT d1.* FROM [database-name] d1
INNER JOIN (
select Names,MAX(Color) as mc,MAX(Shape) as ms
from [database-name]
group by Names
) d2
ON d1.Names = d2.Names
WHERE mc IS NULL
AND ms IS NULL

How to avoid redundant attributes in sql?

I currently have this table.
name title
Robert Pattinson Twilight
Daniel Radcliff NULL
Leonardo Dicaprio NULL
Charlie Chaplin The kid
Charlie Chaplin The Circus
Charlie Chaplin Timelight
John Abraham Dhoom
John Abraham Race 2
Is there a way to avoid duplicate attributes like 'Charlie Chaplin' and get a result as follows?
name title
Robert Pattinson Twilight
Daniel Radcliff NULL
Leonardo Dicaprio NULL
Charlie Chaplin The kid, The Circus,Timelight
John Abraham Dhoom,Race 2

duplicate fields with an inner join

I'm having trouble understanding how to do a multi-table join without generating lots of duplicate fields.
Let's say that I have three tables:
family: id, name
parent: id, family, name
child: id, family, name
If I do a simple select:
select family.id, family.name from family
order by family.id;
I get a simple list:
ID Name
1 Smith
2 Jones
3 Wong
If I add an inner join:
select family.id, family.name, parent.first_name, parent.last_name
from family
inner join parent
on parent.family = family.id
order by family.id;
I get some duplicated fields:
ID Name Parent
1 Smith Howard Smith
1 Smith Janet Smith
2 Jones Phil Jones
2 Jones Harriet Jones
3 Wong Billy Wong
3 Wong Rachel Wong
And if I add another inner join:
select family.id, family.name, parent.first_name, parent.last_name
from family
inner join parent
on parent.family = family.id
inner join child
on child.family = family.id
order by family.id;
I get even more duplicated fields:
ID Name Parent Child
1 Smith Howard Smith Peter Smith
1 Smith Howard Smith Sally Smith
1 Smith Howard Smith Fred Smith
1 Smith Janet Smith Peter Smith
1 Smith Janet Smith Sally Smith
1 Smith Janet Smith Fred Smith
2 Jones Phil Jones Mark Jones
2 Jones Phil Jones Melissa Jones
2 Jones Harriet Jones Mark Jones
2 Jones Harriet Jones Melissa Jones
3 Wong Billy Wong Mary Wong
3 Wong Billy Wong Jennifer Wong
3 Wong Rachel Wong Mary Wong
3 Wong Rachel Wong Jennifer Wong
What I would prefer, because it's more human readable, is something like this:
ID Name Parent Child
1 Smith Howard Smith Peter Smith
Janet Smith Sally Smith
Fred Smith
2 Jones Phil Jones Mark Jones
Harriet Jones Melissa Jones
3 Wong Billy Wong Mary Wong
Rachel Wong Jennifer Wong
I know that one of the benefits of an inner join is to avoid presenting excess information through a Cartesian product. But it seems that I get something similar with a multi-table join. Is there a way to summarize each group as shown above or will this require post-processing with a scripting language like Python?
Thanks,
--Dan
This is precisely the way the relation databases work: each row must contain all information in itself, with every single field that you request. In other words, each row needs to make sense in isolation from all other rows. If you do a single query and you need to get all three levels of information, you need to deal with eliminating duplicates yourself for the desired formatting.
Alternatively, you can run three separate queries, and then do in-memory joins in code. Although this may be desirable in certain rare situations, it is generally a wrong way of spending your development time, because RDBMS are usually much more efficient at joining relational data.
You've hit it on the head. You'll need some post processing to get the results you're looking for.
SQL query results are always simple tabular data, so to get the results you're looking for would definitely not be a pretty query. You could do it, but it would involve quite a bit of query voodoo, storing things in temporary tables or using cursors, or some other funky workaround.
I'd definitely suggest using an external application to retrieve your data and format it appropriately from there.
ORMs like Entity Framework in .NET can probably do this pretty easily, but you could definitely do this with a few nested collections or dictionaries in any language.

Joining SQL Tables

I have two tables:
RecommendedFriends and AddedFriends
each of the tables have a User field and a Friend field. I am trying to figure out how I can see how many friends a User added that they were also recommended. Heres an example of the tables:
RecommendedFriends
User Friends Time
------------------------------------
Jake Eric 8:00am
Jake John 8:00am
Jake Jack 8:30am
Greg John 8:30am
Greg Tim 9:00am
Greg Steve 9:30am
Will Jackson 9:30am
AddedFriends
User Friends Time
------------------------------------
Jake Jack 8:35am
Greg John 8:35am
Greg Tim 9:00pm
Greg Jim 10:30am
Greg Tina 10:45am
Greg Bob 10:00am
Charlie Brian 11:00am
So the table I need would look like this:
Results
User RecFriends AddFriends
------------------------------------
Jake Eric
Jake John
Jake Jack Jack
Greg John John
Greg Tim Tim
Greg Steve
Greg Tina
Will Jackson
Charlie Brian
So I can go in and say 3 people added friends they were recommended, 4 Recommendations failed, and 2 people added someone they weren't recommended.
I think what you want is full outer join:
select coalesce(rf.USER, af.user) as user, rf.friends as RecFriends, af.Friends as AddFriends,
from RecommendedFriends rf full outer join
AddedFriends af
on rf.user = af.user and
rf.Friends = af.Friends
This doesn't take time into account. You might want to check that the time of the add is after the time of the recommendation, if you want to infer causality between the recommendation and the add.
If you are using a database that doesn't support full outer join (can anyone say "MySQL"), you can get the same result doing:
select t.user, MAX(case when which = 'rec' then friends end) as RecFriends,
MAX(case when which = 'add' then friends end) as AddFriends
from ((select rf.user, rf.friends, 'rec' as which
from RecommendedFriends af.user
) union all
(select af.user, af.friends, 'add' as which
from AddedFriends af
)
) t
group by user
This version has the nice feature that it will not produce duplicate records, in the event of multiple recommendations or adds.