I'm working on an insurance comparison platform using Codeigniter.
I have a packages table which looks like this:
+----------+--------------+------------+---------------------+-------------+
| tpckg_id | tpckg_people | tpckg_days | tpckg_policy_amount | tp_name |
+----------+--------------+------------+---------------------+-------------+
| 21 | individual | 10 | 1000 | Test25 |
| 22 | family | 7 | 2000 | Testing |
| 23 | individual | 20 | 600 | TPL Care |
| 24 | family | 10 | 1000 | TPL Care |
| 25 | individual | 15 | 650 | Travel Care |
| 26 | family | 10 | 1100 | TPL Care |
| 27 | individual | 7 | 500 | TPL Care |
| 28 | family | 7 | 1200 | Travel Care |
| 29 | family | 10 | 500 | TPL Care 2 |
| 30 | individual | 11 | 500 | TPL Care |
+----------+--------------+------------+---------------------+-------------+
Now, I'm fetching the data using this query:
$this->db->select('travel_packages.tpckg_id, travel_packages.tpckg_people, travel_packages.tpckg_days, travel_packages.tpckg_policy_amount, travel_products.tp_name');
$this->db->from('travel_packages');
$this->db->join('travel_products', 'travel_products.tp_id = travel_packages.tpckg_products_id')
$this->db->where('travel_packages.tpckg_people', 'Individual');
$this->db->where('travel_packages.tpckg_days >= 10');
$this->db->group_by('travel_packages.tpckg_policy_amount');
$this->db->order_by('travel_packages.tpckg_policy_amount', 'ASC');
As expected is returns all the records which has tpckg_people = individual and tpckg_days >= 10
like this:
+----------+--------------+------------+---------------------+-------------+
| tpckg_id | tpckg_people | tpckg_days | tpckg_policy_amount | tp_name |
+----------+--------------+------------+---------------------+-------------+
| 21 | individual | 10 | 1000 | Test25 |
| 23 | individual | 20 | 600 | TPL Care |
| 25 | individual | 15 | 650 | Travel Care |
| 30 | individual | 11 | 500 | TPL Care |
+----------+--------------+------------+---------------------+-------------+
What I want it to return is only the first greater number of days if there's no equal number than what user has entered. For example if user enters 9 for number of days and I have no package with 9 number of days it should return the first greater number of days of each product.
Like this:
+----------+--------------+------------+---------------------+-------------+
| tpckg_id | tpckg_people | tpckg_days | tpckg_policy_amount | tp_name |
+----------+--------------+------------+---------------------+-------------+
| 21 | individual | 10 | 1000 | Test25 |
| 25 | individual | 15 | 650 | Travel Care |
| 30 | individual | 11 | 500 | TPL Care |
+----------+--------------+------------+---------------------+-------------+
Any help with the query, please? Thanks in advance. :-)
Here's a raw query...
Select x.*
From travel_packages x
Join
( Select tp_name name
, tpckg_people people
, min(tpckg_days) min_days
from travel_packages
where tpckg_people = 'individual'
and tpckg_days >= 9
group
by name
, people
) y
On y.name = x.tp_name
And y.people = x.tpckg_people
And y.min_days = x.tpckg_days;
Related
I have two tables linked by by a column cat_id. I want to retrieve all values of timing in M_Master for which no equivalent exists in Tbl_Appointment.
Example: Tbl_Appointment holds data for timing value 6:15 PM. I want all timing values from M_Master except for 6:15 PM.
Here is data from M_Master
| id | name | timing | cat_id | rate | design_template | type | prefix | vat |
| 109 | | 09:30 AM | 3 | 0 | | TIMING | | 0 |
| 110 | | 09:45 AM | 3 | 0 | | TIMING | | 0 |
| 113 | | 10:15 AM | 3 | 0 | | TIMING | | 0 |
| 115 | | 11:00 AM | 3 | 0 | | TIMING | | 0 |
| 116 | | 11:30 AM | 3 | 0 | | TIMING | | 0 |
| 118 | | 12:30 PM | 3 | 0 | | TIMING | | 0 |
| 121 | | 1:30 PM | 3 | 0 | | TIMING | | 0 |
| 125 | | 2:30 PM | 3 | 0 | | TIMING | | 0 |
| 127 | | 6:15 PM | 3 | 0 | | TIMING | | 0 |
and here is data from Tbl_Appointment
| id | cancel | name | mobileno | age | sex | payment_told | test_id | referredby | app_given | sentsms | timing | cat_id | app_date |
| 94 | 0 | TEST2 | 7985462313 | 45 | 1 | 800.00 | 123 | 14 | QWERTY | 1 | 06:15 PM | 3 | 2016-01-01 |
Based on the information provided so far, you could try along
SELECT
DATE_FORMAT(M.timing, '%h:%i %p') AS timing
FROM M_Master M
JOIN Tbl_Appointment A
ON M.cat_id = A.cat_id
AND A.app_date = '2016-01-01'
AND M.timing != A.timing
ORDER BY M.timing
;
See it in action: SQL Fiddle.
Please comment if and as this requires adjustment / further detail.
This question already has answers here:
subtract "1" from the number in a row SQL Query [duplicate]
(3 answers)
Closed 8 years ago.
I am new in my sql and can not really figure out how to do it.
I have a two tables.
trucks
select * from trucks;
+----+---------+----------+--------+--------------+
| id | size | quantity | status | customers_id |
+----+---------+----------+--------+--------------+
| 12 | 10_feet | 3 | active | 0 |
| 13 | 10_feet | 3 | active | 0 |
| 14 | 10_feet | 2 | active | 0 |
| 15 | 14_feet | 5 | active | 0 |
| 16 | 14_feet | 2 | active | 0 |
| 17 | 14_feet | 2 | active | 0 |
| 18 | 17_feet | 2 | active | 0 |
| 19 | 17_feet | 2 | active | 0 |
| 20 | 24_feet | 3 | active | 0 |
| 21 | 10_feet | 1 | active | 0 |
| 22 | 24_feet | 1 | active | 0 |
+----+---------+----------+--------+--------------+
and truck_customers
select * from truck_customers;
+----+--------+----------+--------+------------------+---------+------------+
| id | first | last | dl | email | size | date_in |
+----+--------+----------+--------+------------------+---------+------------+
| 3 | Poul | Jons | A13324 | poul#gmail.com | 10_feet | 2013-11-30 |
| 4 | Poul | Watson | A23439 | watson#gmail.com | 10_feet | 2013-11-30 |
| 5 | Alex | Snders | A22 | Alex#gmail.com | 17_feet | 2013-11-30 |
| 6 | santes | Garsia | A18337 | Santes#gmail.com | 10_feet | 2013-11-30 |
| 7 | James | Bond | JB111 | Bond#gmail.com | 10_feet | 2013-11-30 |
| 8 | John | Travolta | G123 | Gohn#gmail.com | 14_feet | 2013-11-30 |
+----+--------+----------+--------+------------------+---------+------------+
When entering information into truck_customers, it should automatically subtract
one item from trucks table based on the size.
Using
$sql = " UPDATE trucks SET quantity = -- WHERE size = '$size'";
But it does not work.
I can send you my code if it is going to be easier to understand.
You're almost there.
UPDATE trucks SET quantity = quantity-1 WHERE size = '$size'
Fiddle
Not only would your code not work, but you'd lose your WHERE conditions too...
-- this is a comment in SQL
http://dev.mysql.com/doc/refman/5.0/en/comments.html
You need to assign to original variable plus/minus increment, as Hanky Panky mentioned above.
I want to concatenate and count data of the same column, so I can concatenate but I can not count the repeated data.
Here's my table of data:
| ID | bills | class |
|-----|-------|-------|
| 1 | 0.5 | 2 |
| 2 | 1 | 1 |
| 3 | 0.5 | 2 |
| 5 | 1 | 3 |
| 6 | 0 | 2 |
| 7 | 0.5 | 1 |
| 8 | 1 | 2 |
| 9 | 1 | 3 |
| 10 | 0.5 | 1 |
| 11 | 0 | 2 |
| 12 | 1 | 1 |
| 13 | 0 | 3 |
| 14 | 1 | 2 |
| 15 | 0 | 1 |
| 16 | 0 | 1 |
| 17 | 0.5 | 3 |
| 18 | 0 | 3 |
| 13 | 0.5 | 3 |
Here's my sql query I'm using to concatenate data:
SELECT class AS lesson,
GROUP_CONCAT( bills ORDER BY bills ) AS bills
FROM tb_presence
GROUP BY class;
Here's my result below:
| class | bills |
|-------|------------------|
| 1 | 1,0.5,0.5,1,0,0 |
| 2 | 0.5,0,1,0,1 |
| 3 | 1,1,0,0.5,0,0.5 |
Now I would like to count the data that are equal, but continue with the same concatenation.
I want to "count" the data with the same values and display concatenated (column observation and only to help understanding)
| class | bills | observation |
|-------|-------|-----------------------------|
| 1 | 2,2,2 | (2=0+0) (2=0.5+0.5) (2=1+1) |
| 2 | 2,1,2 | (2=0+0) (1=0.5) (2=1+1) |
| 3 | 2,2,2 | (2=0+0) (2=0.5+0.5) (2=1+1) |
Is this really possible?
Here is a solution (thanks to #wchiquito for the sqlfiddle) See http://sqlfiddle.com/#!2/2d2c8/1
As you can see it cannot dynamically determine the bills' values and count them. But there is a count per bill value that you want.
SELECT class AS lesson,
GROUP_CONCAT( bills ORDER BY bills ) AS bills
,SUM(IF(bills=0,1,0)) AS Count0
,SUM(IF(bills=0.5,1,0)) AS Count05
,SUM(IF(bills=1,1,0)) AS Count1
,COUNT(*) AS totalRecords
,COUNT(*)
- SUM(IF(bills=0,1,0))
- SUM(IF(bills=0.5,1,0))
- SUM(IF(bills=1,1,0))
AS Missing
FROM tb_presence GROUP BY class;
I added an extra record to show how the 'missing' column could show if you were not taking all values into consideration.
Results
| LESSON | BILLS | COUNT0 | COUNT05 | COUNT1 | TOTALRECORDS | MISSING |
|--------|-----------------------------------------|--------|---------|--------|--------------|---------|
| 1 | 0.00,0.00,0.50,0.50,1.00,1.00,1.00,4.00 | 2 | 2 | 3 | 8 | 1 |
| 2 | 0.00,0.00,0.50,0.50,1.00,1.00 | 2 | 2 | 2 | 6 | 0 |
| 3 | 0.00,0.00,0.50,0.50,1.00,1.00 | 2 | 2 | 2 | 6 | 0 |
I have a database table campaign_data. I need to select the customer_id where in the campaign there is difference in tariff. How can i do that with MySQL query. Here is some sample data.
SQL Fiddle Schema
| CAMPAIGN_ID | CUSTOMER_ID | CAMPAIGN_NAME | TARIFF |
---------------------------------------------------------
| 1 | 1 | Richmond | 100 |
| 2 | 1 | Sutton Coldfield | 75 |
| 3 | 1 | Putney | 100 |
| 4 | 1 | Kentish Town | 100 |
| 5 | 1 | Woking | 100 |
| 6 | 2 | Chiswick | 90 |
| 7 | 2 | Ealing | 100 |
| 8 | 2 | Camden | 100 |
| 9 | 3 | Croydon | 75 |
| 10 | 3 | Croydon1 | 100 |
| 11 | 3 | Archway | 100 |
| 12 | 4 | Ealing0 | 100 |
| 13 | 4 | Ealing01 | 100 |
| 14 | 4 | Ealing02 | 100 |
| 15 | 4 | Chingford | 100 |
| 16 | 4 | chingford01 | 100 |
Now as you can see customer id 1 , and 3 has different tariffs. I want to select them and leave the customer id 4 because it has campaigns with same tariffs.
Desired Output
| CUSTOMER_ID |
---------------
| 1 |
| 2 |
| 3 |
For clearification you can see customer 1 has 5 records. If in his 5 records the tariff is same (100) i want to avoid but if the tariff is not some as 4 records have 100 and one has 75, i want to select.
SELECT customer_id, count(DISTINCT tariff) as tariffs
FROM campaign_data
GROUP BY customer_id
HAVING tariffs > 1
you looking for this maybe
SELECT customer_id
FROM campaign_data
GROUP BY customer_id
HAVING count(DISTINCT tariff) > 1
http://sqlfiddle.com/#!2/48b6e/31
select
customer_id,
tariff
from campaign_data
group by customer_id
having sum(tariff)/count(tariff) <> tariff;
I have two tables in a tournament-related database and I need to know the most optimized SQL query to generate the correct overall results. The results must show the total points scored, minus any penalties, and scores that are tied should be broken based on the person who reached that score first.
In the database tables, I have an event log where each score is added as teams proceed through the tournament, and I have another table which shows which team is part of which tournament.
Table "xTournamentTeam" (connects a team to a tournament)
=======================
+-----+------------+--------+--------------+
| nID | Team Name | TeamID | TournamentID |
+-----+------------+--------+--------------+
| 1 | Team A | 12 | 25 |
| 2 | Team B | 13 | 25 |
| 3 | Team C | 14 | 25 |
| 4 | Team D | 15 | 25 |
| 3 | Team A | 12 | 32 |
| 4 | Team B | 13 | 32 |
+-----+------------+--------+--------------+
Table "nEventLog" (records scoring during a tournament)
=================
+-----+---------------+---------+----------+----------------+-----------------------+
| nID | nTournamentID | nTeamID | nPoints | nPointsPenalty | nEventTime |
+-----+---------------+---------+----------+----------------|-----------------------+
| 1 | 25 | 15 | 100 | 0 | 1/24/2013 6:05:14 AM |
| 2 | 25 | 14 | 100 | 0 | 1/24/2013 6:29:55 AM |
| 3 | 25 | 14 | 100 | 25 | 1/24/2013 7:09:34 AM |
| 4 | 25 | 12 | 100 | 0 | 1/24/2013 7:12:28 AM |
| 5 | 25 | 12 | 100 | 0 | 1/24/2013 8:42:59 AM |
| 6 | 25 | 12 | 100 | 50 | 1/24/2013 8:43:36 AM |
| 7 | 25 | 14 | 100 | 0 | 1/24/2013 9:15:24 AM |
| 8 | 25 | 15 | 100 | 0 | 1/24/2013 9:15:27 AM |
| 9 | 32 | 12 | 100 | 0 | 1/28/2013 8:33:49 AM |
| 10 | 32 | 13 | 100 | 25 | 1/28/2013 2:15:12 PM |
| 11 | 32 | 12 | 100 | 10 | 1/28/2013 7:12:25 AM |
| 12 | 32 | 13 | 100 | 0 | 1/29/2013 7:18:06 AM |
+-----+---------------+---------+----------+----------------+-----------------------+
In the case of the above data, the query I need should generate the following results for Tournament #25:
+-------+------------+--------+--------------+---------------+---------------------+-----------------------------+
| nRank | Team Name | TeamID | TournamentID | nTotalPoints | nTotalPointsPenalty | nLatestEventTime |
+-------+------------+--------+--------------+---------------+---------------------+-----------------------------+
| 1 | Team A | 12 | 25 | 300 | 50 | 1/24/2013 8:43:36 AM |
| 2 | Team C | 14 | 25 | 300 | 25 | 1/24/2013 9:15:24 AM |
| 3 | Team D | 15 | 25 | 200 | 0 | 1/24/2013 9:15:27 AM |
| 4 | Team B | 13 | 25 | 0 | 0 | |
+-------+------------+--------+--------------+---------------+---------------------+-----------------------------+
For load purposes, I'm trying to avoid sub-queries at all costs since the final query should be as optimized as possible. The "nRank" column can be generated programatically... MySQL shouldn't have to return it, but I'm shoing it for reference.
The query I have that is the closest is this one, but it doesn't return "Team B" because they don't have any records in the "nEventLog" table for nTournamentID #25:
SELECT xTournamentTeam.nTeamName
, sum(nEventLog.nPoints) AS nTotalPoints
, xTournamentTeam.nTeamID
, max(nEventLog.nEventTime) AS nLatestEventTime
, sum(nEventLog.nPointsPenalty) AS nTotalPenaltyPoints
, xTournamentTeam.nTournamentID
FROM
xTournamentTeam
LEFT OUTER JOIN nEventLog
ON xTournamentTeam.nTeamID = nEventLog.nTeamID
WHERE
xTournamentTeam.nTournamentID = 33
AND nEventLog.nTournamentID = 33
GROUP BY
xTournamentTeam.nID
, xTournamentTeam.nTournamentID
ORDER BY
nTotalPoints DESC
, nLatestEventTime DESC
I'm certainly no expert in MySQL queries, and I've been working on this for two days without much success, so any help would be greatly appreciated.
I change your logic a little bit, I think it's working:
SELECT
xTournamentTeam.TeamName
, sum(nEventLog.nPoints) AS nTotalPoints
, xTournamentTeam.TeamID
, max(nEventLog.nEventTime) AS nLatestEventTime
, sum(nEventLog.nPointsPenalty) AS nTotalPenaltyPoints
, xTournamentTeam.TournamentID
FROM
xTournamentTeam
LEFT OUTER JOIN nEventLog
ON xTournamentTeam.TournamentID = nEventLog.nTournamentID AND xTournamentTeam.TeamID = nEventLog.nTeamID
WHERE
xTournamentTeam.TournamentID = 25
GROUP BY
xTournamentTeam.TeamID
, xTournamentTeam.TournamentID
, xTournamentTeam.TeamName
ORDER BY
nTotalPoints DESC
If you need, you can format nulls to represent 0 or something else.