MySQL query does count then display additional data - mysql

This current query works great and gives me a count of how many times and office occurs in the table for each record and the office name. How do I expand this query to first display the Office and Count like it currently does and THEN displays colums lastName, Phone underneath the count of each record that matched the Office and then moves onto the next Office and Office(Count) and displays those lastname, Phone records and so forth? Is that possible in MySQL?
SELECT Office, COUNT(Office) AS c
FROM Active
GROUP BY Office
HAVING COUNT(Office) >= 5 ORDER BY c DESC
Example:
Office1 | 2
Office1 | lastName | Phone
Office1 | lastName | Phone
Office2 | 3
Office2 | lastName | Phone
Office2 | lastName | Phone
Office2 | lastName | Phone

No you cannot do that. Your best bet would be UNION, but you must have identical number of columns and column types, which doesn't match your criteria.
Why don't you try
SELECT Office, lastName, Phone FROM Active ORDER BY Office
and in your programming language, parse the rows and use a counter variable to count identical Office records, and build your own table.
Edit: You say it's for exporting directly to a spreadsheet. You could do this in two queries: Do your count() query, and then do the query I have above. Export the two results and mix them in a spreadsheet as you need. Hey, it gets the job done.

You can try to use MySQL's UNION, but the number of the columns, and the column names would have to be identical.
Overall this seems like a wrong approach. Try rethinking your logic where you don't need this sort of output.
I would suggest receiving just the lastname and phone, and caching the results, then parsing them. The COUNT(*) is technically redundant information since the number of rows with identical Office already describes that.

Related

Using Lookup and getting a count from each Dataset

I have two datasets and I'm using Lookup to get one result, but the total is only from one dataset. I've tried and tried, but I'm having no luck.
First Dataset is called MedCond
This is the Data:
Drug_Name
Start_Date
Stop_Date
InmateID
Drug_Indication
Created
ID
Second Dataset is called ProblemList
This is the Data:
Medical_Condition
Inmate_ID
Created
ID
Drug Indication and Medical Condition are the same. I want to get a combined total of both.
This only gives me the count of the Drug Indications (which I have them grouped on) =Count(Lookup(Fields!Drug_Indication.Value,Fields!Medical_Condition.Value,Fields!Medical_Condition.Value, "ProblemList"))
I feel like I've tried everything under the sun. I'm extremely exasperated. I'm trying to get a total of each of the conditions/Indications that come from each dataset. For instance, One condition/Indication might be Addiction. There may be four addictions in from the Drug_Indication in the MedCon dataset and five addictions from the Medical_Condition in the ProblemList. I want to see Addictions 9 on the table and so and so forth for each Drug Indication/Medical Condition.
Thanks in advance for your help! Save my sanity. :) I'm sure it's probably something simple?
Tara
Thank you. I've tried using the Inmate_ID and InmateID as the key to join, but I still end up with only one of counts of either Medical_Condition or Drug_Indication.
As an example, there might be 10 addictions in one and 15 addictions in the other. I need them to be grouped under the title addiction (and whatever other titles there might be) with the total being 25.
It would look something like this.
Example Look
Something like this is close, but the counts aren't quite right.
=Count(Lookup(Fields!InmateID.Value, Fields!Inmate_ID.Value, Fields!Medical_Condition.Value, "ProblemList")) + Count(Fields!Drug_Indication.Value)
Maybe it's the way I'm grouping? How do you group on a combination of values such as Medical_condition and Drug_Indication?
Thanks again!
Tara
I think you used the Lookup() wrong. When I look at your two datasets (for me) the key to join the two datasets would be Inmate_ID.
=Lookup(Fields!InmateID.Value, Fields!Inmae_ID.Value, Fields!Medical_Condition.Value, "SecondDatasetName")
This would result in a table like this (The last column comes form the lookup above):
Drug_Name | Start_Date | Stop_Date | InmateID | Drug_Indication | Created | ID | Medical_Condition
Now you can just get the total per column:
Drug_Name | Start_Date | Stop_Date | InmateID | Drug_Indication | Created | ID | Medical_Condition
Total1 Total2
To sum Total1 and Total2 you can add a new tablix and reference to the textbox totals like this:
=ReportItems!Total1TextboxName.Value + ReportItems!Total2TextboxName.Value

How to make a single MySQL query that uses the results of another query

I have a Perl program that queries a MySQL database to bring back results based upon which "report" option a user has selected from a web page.
One of the reports is all occupants of a student housing building who have applied for a parking permit, but who have not yet been given one.
When the students apply for a permit, it records the specifics about their car (make, model, year, color, etc.) in a single table row. Each apartment can have up to three students, and each student may apply for a permit. So an apartment might have 0 permits, or 1, 2, or 3 permits, depending upon how many of them have cars.
What I'd like to be able to do, is execute a MySQL query that will find out how many occupants in each apartment have applied for a parking permit, and then based on the results of that query, find out how many permits have been issued. If the number of permits issued is less than the number of applications, that apartment number should be returned in the result set. It doesn't have to name the specific occupant, just the fact that the apartment has at least one occupant who has applied for a permit, but not yet received one.
So I have two tables, one is called occupant_info and it contains all kinds of info about the occupant, but the relevant fields are:
counter (a unique row id)
parking_permit_1_number
parking_permit_2_number
parking_permit_3_number
When a parking permit has been assigned, it is recorded in the appropriate parking_permit_#_number field (if it's occupant number one's permit, it would be recorded in parking_permit_1_number, etc.).
The second table is called, parking_permits, and contains all of the car/owner specifics (make, model, year, owner, owner address, etc.). It also contains a field which references the counter from the occupant_info table.
So an example would be:
occupant_info table
counter | parking_permit_1_number | parking_permit_2_number | parking_permit_3_number
--------|-------------------------|-------------------------|------------------------
1 | 12345 | | 98765
2 | 43920 | |
3 | 30239 | | 34233
parking_permits table
counter | counter_from_occupant_info | permit_1_name | permit_2_name | permit_3_name
--------|----------------------------|---------------|-----------------|-------------------
1 |2 | David Jones | James Cameron | Michael Smerconish
2 |3 | Bill Epps | Hillary Clinton | Donald Trump
3 |1 | Joanne Miller | | Sridevi Gupta
I want a query that will first look at how many occupants in an apartment have applied for a permit. This is determined by counting the names in the parking_permits table. In that table, row 1 has three names, row 2 has three names, and row 3 has two names. The query should then look at the occupant_info table, and for each counter_from_occupant_info from the parking_permits table, see if the same number of parking permits have been issued. This can be determined by comparing the number of non-blank parking_permit_#_number fields.
Using the data above, the query would see the following :
parking_permit table row 1
Has counter_from_occupant_info equal to "2"
Has three names
The row in occupant_info with counter = "2" has only one permit number issued,
so counter_from_occupant_info 2 from parking_permits should be in the result set.
parking_permit table row 2
Has counter_from_occupant_info equal to "3"
Has three names
The row in occupant_info with counter = "3" has only two permit numbers issued,
so counter_from_occupant_info 3 from parking_permits should be in the result set.
parking_permit table row 3
Has counter_from_occupant_info equal to "1"
Has two names
The row in occupant_info with counter = "1" has two permit numbers issued,
so this row should *not* be in the result set.
I've thought about using if, then, case, when, type logic to do this in one query, but frankly can't wrap my head around how to do so.
I was thinking something like:
SELECT
CASE WHEN ( SELECT counter_from_occupant_info
FROM parking_permits
WHERE parking_permit_1_name != ""
AND parking_permit_2_name != ""
AND parking_permit_3_name != "" ) THEN
IF ( SELECT parking_permit_1_number,
parking_permit_2_number,
parking_permit_3_number
FROM occupant_info
WHERE counter = ***somehow reference counter from above case statement--I don't know how to do this***
But then my head explodes and I realize I don't know what the heck I'm doing.
Any help would be appreciated. :-)
Doug
You have a few problems:
Your occupants table schema is bad. There's worse out there, but it looks like someone that doesn't understand how a database works built this table.
Your permits table is also bad. Same reason.
You have no idea what you are doing (kidding... kidding...)
Problem 1:
Your occupants table should probably be two tables. Because an occupant could have 0-3 permits (possibly more, I can't tell from the sample data) then you need a table for your occupant's attributes (name, height, gender, age, primary smell, favorite color, first rent date, I dunno).
Occupants
OccupantID | favorite TV Show | number of limbs | first name | last name | aptBuilding
And... another table for Relationship between the occupant and the permit:
Occupant_permits
OccupantID | Permit ID | status
Now... an occupant can have as many permits as you can stuff into that table and the relationship between them has a status "Applied for", or "Granted" or "Revoked" or what have you.
Problem 2
Your permit info table is doing double duty as well. It holds the information about a permit (it's name) as well as the relationship to the occupant. Since we already have a relationship to the occupant with the "Occupant_Permits" table above, we just need a permits table to hold attributes of a permit:
Permits
Permit ID | Permit Name | Description | etc..
Problem 3
Now that you have a correct schema where objects are in their own table (Occupant, Permit, Occupant and Permit Relationship) your query to get a list of apartments that have at least one occupant that has applied, but not yet received a permit would be:
SELECT
COUNT(DISTINCT o.AptBuilding)
FROM
occupants as o
INNER JOIN occupants_permit as op
ON o.occupant_id = op.occupant_id
INNER JOIN permits as p
ON op.permit_id = p.permit_id
WHERE
op.Status = "Applied"
That's nice and simple and you aren't relying on CASE or UNION or count comparison or any fancy stuff. Just nice straight joins and a simple WHERE clause. This will be fast to query and there's no funny business.
Because your schema isn't great, in order to get something similar you'll need to make use of either UNION queries to stack your many permit_N_ fields into a single field and run something similar to the above query, or you'll have use a fair amount of CASE/IF statements:
SELECT DISTINCT p.pCounter
FROM
(
SELECT
counter as Ocounter
CASE WHEN parking_permit_1_number IS NOT NULL THEN 1 ELSE 0 END
+
CASE WHEN parking_permit_2_number IS NOT NULL THEN 1 ELSE 0 END
+
CASE WHEN parking_permit_3_number IS NOT NULL THEN 1 ELSE 0 END AS permitCount
FROM occupant_info
) as o
LEFT OUTER JOIN
(
SELECT
counter_from_occupant_info as pCounter
CASE WHEN parking_permit_1_name IS NOT NULL THEN 1 ELSE 0 END
+
CASE WHEN parking_permit_2_name IS NOT NULL THEN 1 ELSE 0 END
+
CASE WHEN parking_permit_3_Name IS NOT NULL THEN 1 ELSE 0 END AS permitPermitCount
) as p ON o.Ocounter = p.Pcounter
WHERE p.permitCounter > o.PermitCount
I'm not 100% convinced that is exactly what you are looking for since your schema is confusing where you have multiple objects in a single table and everything is pivoted, but... it should get you in the ball park.
This will be much slower too. There's intermediate result sets, CASE statements, and math, so don't expect MySQL to spit this out in milliseconds.

MySQL - Difficulty getting sum with other data between two tables

I am using the Invision Power Board suite for purchases, but they do not provide a way to get the total a customer has paid. So I am attempting to write an SQL Query for this information. My knowledge of SQL is extremely limited, so ... I may be taking the wrong approach.
From what I have gathered, the information I need is on two tables, but the way it outputs is not useful to me since it outputs every individual purchase, with only the member's unique ID (relatively useless in bulk operations and examination)
I have so far gotten to this point...
SELECT member_id, email, name,
SUM(ibf_nexus_invoices.i_total) as SUM_TOTAL
FROM ibf_members
RIGHT JOIN ibf_nexus_invoices ON ibf_members.member_id = ibf_nexus_invoices.i_member
WHERE ibf_nexus_invoices.I_status = "paid";
This takes everything from the members table and the invoices table, and outputs it like this..
------------------------------------------------------------
member_id | email | name | SUM_TOTAL |
------------------------------------------------------------
4 | email#domain.com | "Derek" | 184.22 |
------------------------------------------------------------
At first glance, this looks like what I want. But it only returns one person, not all of the people in the member's list. Is anyone versed enough with SQL to help steer me in the right direction?
You need to add
GROUP BY member_id
to the end of the query to get a row per person. Otherwise, aggregate functions like SUM() combine all the rows in the result.

MySQL, how to repeat same line x times

I have a query that outputs address order data:
SELECT ordernumber
, article_description
, article_size_description
, concat(NumberPerBox,' pieces') as contents
, NumberOrdered
FROM customerorder
WHERE customerorder.id = 1;
I would like the above line to be outputted NumberOrders (e.g. 50,000) divided by NumberPerBox e.g. 2,000 = 25 times.
Is there a SQL query that can do this, I'm not against using temporary tables to join against if that's what it takes.
I checked out the previous questions, however the nearest one:
is to be posible in mysql repeat the same result
Only gave answers that give a fixed number of rows, and I need it to be dynamic depending on the value of (NumberOrdered div NumberPerBox).
The result I want is:
Boxnr Ordernr as_description contents NumberOrdered
------+--------------+----------------+-----------+---------------
1 | CORDO1245 | Carrying bags | 2,000 pcs | 50,000
2 | CORDO1245 | Carrying bags | 2,000 pcs | 50,000
....
25 | CORDO1245 | Carrying bags | 2,000 pcs | 50,000
First, let me say that I am more familiar with SQL Server so my answer has a bit of a bias.
Second, I did not test my code sample and it should probably be used as a reference point to start from.
It would appear to me that this situation is a prime candidate for a numbers table. Simply put, it is a table (usually called "Numbers") that is nothing more than a single PK column of integers from 1 to n. Once you've used a Numbers table and aware of how it's used, you'll start finding many uses for it - such as querying for time intervals, string splitting, etc.
That said, here is my untested response to your question:
SELECT
IV.number as Boxnr
,ordernumber
,article_description
,article_size_description
,concat(NumberPerBox,' pieces') as contents
,NumberOrdered
FROM
customerorder
INNER JOIN (
SELECT
Numbers.number
,customerorder.ordernumber
,customerorder.NumberPerBox
FROM
Numbers
INNER JOIN customerorder
ON Numbers.number BETWEEN 1 AND customerorder.NumberOrdered / customerorder.NumberPerBox
WHERE
customerorder.id = 1
) AS IV
ON customerorder.ordernumber = IV.ordernumber
As I said, most of my experience is in SQL Server. I reference http://www.sqlservercentral.com/articles/Advanced+Querying/2547/ (registration required). However, there appears to be quite a few resources available when I search for "SQL numbers table".

MySQL Query Search using Multiple Rows

Firstly I'd like to start by apologizing for the potentially miss-leading title... I am finding it difficult to describe what I am trying to do here.
With the current project I'm working on, we have setup a 'dynamic' database structure with MySQL that looks something like this.
item_details ( Describes the item_data )
fieldID | fieldValue | fieldCaption
1 | addr1 | Address Line 1
2 | country | Country
item_data
itemID | fieldID | fieldValue
12345 | 1 | Some Random Address
12345 | 2 | United Kingdom
So as you can see, if for example I wanted to lookup the address for the item 12345 I would simply do the statement.
SELECT fieldValue FROM item_data WHERE fieldID=1 and itemID=12345;
But here is where I am stuck... the database is relatively large with around ~80k rows and I am trying to create a set of search functions within PHP.
I would like to be able to perform a query on the result set of a query as quickly as possible...
For example, Search an address name within a certain country... ie: Search for the fieldValue of the results with the same itemID's as the results from the query:
'SELECT itemID from item_data WHERE fieldID=2 and fieldValue='United Kingdom'..
Sorry If I am unclear, I have been struggling with this for the past couple of days...
Cheers
You can do this in a couple of ways. One is to use multiple joins to the item_data table with the fieldID limited to whatever it is you want to get.
SELECT *
FROM
Item i
INNER JOIN item_data country
ON i.itemID = country.itemID
and fieldid = 2
INNER JOIN item_data address
ON i.itemID = country.itemID
and fieldid = 1
WHERE
country.fieldValue= 'United Kingdom'
and address.fieldValue= 'Whatever'
As an aside this structure is often referred to as an Entry Attribute Value or EAV database
Sorry in advance if this sounds patronizing, but (as you suggested) I'm not quite clear what you are asking for.
If you are looking for one query to do the whole thing, you could simply nest them. For your example, pretend there is a table named CACHED with the results of your UK query, and write the query you want against that, but replace CACHED with your UK query.
If the idea is that you have ALREADY done this UK query and want to (re-)use its results, you could save the results to a table in the DB (which may not be practical if there are a large number of queries executed), or save the list of IDs as text and paste that into the subsequent query (...WHERE ID in (...) ... ), which might be OK if your 'cached' query gives you a manageable fraction of the original table.