Related
I'm working on a legacy database system which deals with property reports and I am attempting to update a query which shows multiple reports within a time period for the same address. I am using MySQL Workbench to run this query.
The table has a UPRN field for unique addresses, which is fine, however addresses can be manually added without a UPRN. The table also has address1, address2, address3, town, postcode fields. There is NO field which contains the whole address as one line.
We already have a query which uses the UPRN field to generate a list of multiple records within a timescale; however, this will obviously exclude multiple reports without a UPRN.
SELECT * FROM
`rep_base_report` `rep`
WHERE
`rep`.`UPRN` IN (SELECT
`rep2`.`UPRN` AS `UPRN`
FROM
`rep_base_report` `rep2`
WHERE
`rep2`.`STATUS` = 'LODGED'
AND `rep2`.`GENERATED_DATE` > (CURDATE() - INTERVAL 3 MONTH)
GROUP BY `rep2`.`UPRN`
HAVING (COUNT(0) > 1)
ORDER BY `rep2`.`GENERATED_DATE` DESC)
GROUP BY `rep`.`RepReference`
ORDER BY `rep`.`UPRN`
In my head, if I could CONCAT address1, address2 and postcode and use this as the basis for the check, it would give the appropriate output, but I've no idea how to accomplish this.
I've attempted the following but it's giving fewer values that I was expect (I've manually checked some sample data in Excel to see what I should be expecting).
SELECT *
FROM `rep_base_report` `rep`
WHERE
#property :=CONCAT(`rep`.`ADDRESS1`, ' ' ,`rep`.`ADDRESS2`, ' ' ,`rep`.`POSTCODE`) IN (
SELECT #property2 :=CONCAT(`rep2`.`ADDRESS1`, ' ' ,`rep2`.`ADDRESS2`, ' ' ,`rep2`.`POSTCODE`) AS `PROPERTY`
FROM `rep_base_report` `rep2`
WHERE `rep2`.`STATUS` = 'LODGED'
AND `rep2`.`GENERATED_DATE` > CURDATE() - INTERVAL 3 MONTH
GROUP BY #property2
HAVING COUNT(0) > 1
ORDER BY `rep2`.`GENERATED_DATE` DESC
)
GROUP BY `rep`.`RepReference`
ORDER BY `rep`.`UPRN`
SELECT *
FROM `rep_base_report` `rep`
WHERE
CONCAT(`rep`.`ADDRESS1`, ' ', `rep`.`ADDRESS2`, ' ', `rep`.`POSTCODE`) IN (
SELECT CONCAT(`rep2`.`ADDRESS1`, ' ', `rep2`.`ADDRESS2`, ' ', `rep2`.`POSTCODE`) AS `PROPERTY`
FROM `rep_base_report` `rep2`
WHERE `rep2`.`STATUS` = 'LODGED'
AND `rep2`.`GENERATED_DATE` > CURDATE() - INTERVAL 3 MONTH
GROUP BY CONCAT(`rep2`.`ADDRESS1`, ' ', `rep2`.`ADDRESS2`, ' ', `rep2`.`POSTCODE`)
HAVING COUNT(0) > 1
ORDER BY `rep2`.`GENERATED_DATE` DESC
)
GROUP BY `rep`.`RepReference`
ORDER BY `rep`.`UPRN`
I have the table in mysql with records:
I've written the sql query:
SELECT COUNT(*) AS number_of_contacts, channel_id, direction
FROM cic_case_contacts
WHERE case_id = 328678
GROUP BY channel_id, direction
and the result looks like:
I would like to obtain something like below(based on above data):
I was trying to obtaining that with sql query by using my_sql_function GROUP_CONCAT but it dosen't work:
SELECT COUNT(*) AS number_of_contacts, channel_id, GROUP_CONCAT(direction SEPARATOR ', ') AS directions
FROM cic_case_contacts
WHERE case_id = 328678 AND id IN(149196, 149195, 149194, 149193, 149192) AND `office_id` = 10
GROUP BY channel_id
ORDER BY channel_id
I would be greateful for help.
You can use GROUP_CONCAT on a sub query as follows:
SELECT channelid, GROUP_CONCAT(
CONCAT(direction, ': ', c)
ORDER BY direction
SEPARATOR ', '
) AS summary
FROM (
SELECT channelid, direction, COUNT(*) AS c
FROM t
GROUP BY channelid, direction
) x
GROUP BY channelid
Or simply use conditional aggregation:
SELECT channelid, CONCAT_WS(', ',
CONCAT('in: ', COUNT(CASE WHEN direction = 'in' THEN 1 END)),
CONCAT('out: ', COUNT(CASE WHEN direction = 'out' THEN 1 END))
) AS summary
FROM t
GROUP BY channelid
You can use Concat in MySQL
drop table if exists Demo;
CREATE TABLE Demo
(
ID INT AUTO_INCREMENT PRIMARY KEY,
channelid int,
Name VARCHAR(20)
);
INSERT INTO Demo(channelid, Name)VALUES
(1,'in'),(1,'out'),(1,'in'),(1,'out'),(2,'in'),(2,'out'),(1,'in'),(1,'out'),(1,'in'),(2,'out'),(2,'in'),(2,'out'),(2,'in'),(1,'in'),(1,'in');
Query
SELECT SQL_CALC_FOUND_ROWS
channelid,
group_concat ( concat(name,':',channelid) )
FROM Demo
group by channelid;
SELECT FOUND_ROWS();
See the results the the fiddle
Please find below working code as per your requirement :
select tb.channelid, group_concat
(
concat(tb.name,':',tb.MyCol2Count)
) as v1
from
(Select tbl.channelid,tbl.name,(LENGTH(tbl.val) - LENGTH(REPLACE(tbl.val,",","")) + 1) AS MyCol2Count
from
(SELECT channelid, group_concat
(
concat(name,':',channelid)
) as val,name
FROM Demo
group by channelid,Name) as tbl) as tb group by tb.channelid
You can check on below screenshot : http://springinfosoft.com/code/Groupby_code.png
I need to create a stored procedure that will return the total count for each unique value encountered in a pipe-delimited field, roughly in the format in figure 2. Fortunately, the values will only ever be "value1", "value2", or "value3" if that makes things any simpler. I had originally planned to output the data and sort it in PHP by exploding the data and looping through for string matches, but there are extraordinary circumstances that require me to use a stored procedure and I've not used stored procedures before.
The data I'm interpreting is in the format shown below, where the 'valuelist' field is a pipe-delimited field containing many values. I need to find out how many times the values occurred each for a given date.
(figure 1 below) What the data looks like in the database.
id, date, valuelist
1, 2017-01-01, value1|value2|value3
2, 2017-01-01, value1|value2
3, 2017-01-01, value1
So a query of select date, valuelist from db.table where id = 1; will return 2017-01-01, value1|value2|value3.
(figure 2 below) Desired count output representing how many times each value occurred on a specific date. For example, using the data from figure 1, if we ask about 2017-01-01, the output should look something like this.
value1: 3
value2: 2
value3: 1
Assuming you are converting 3|2|1 to separate rows of 3, 2, 1; MySQL (or pretty much any SQL-based RDBMS) does not lend itself well to that kind of output.
Without going into actual procedure code, in a procedure you could:
Store value in a local variable
Use a more general purpose stored function (should be easy to find one around here) to "split" the string on your delimiter |; or "loop" through your string using a "get n-th" function to split it iteratively.
Store values into a temp table
Use a SELECT on the temp table as your procedure's resultset.
Take a look at this:
Detailed as given sample data:
SELECT date,fval as allValue,count(fval) as ValueCount from
(select date,fval from
(select date,SUBSTRING_INDEX(rplace, ' ', 1)fval,SUBSTRING_INDEX(MID(rplace,8,LENGTH(rplace)), ' ', 1)sval,SUBSTRING_INDEX(MID(rplace,15,LENGTH(rplace)), ' ', 1)tval from
(select id, date, valuelist,REPLACE(valuelist,'|',' ') as rplace from
(select 1 as id, '2017-01-01' as date, 'value1|value2|value3' as valuelist union all
select 2, '2017-01-01', 'value1|value2' union all
select 3, '2017-01-01', 'value1') as a)as a) as a
union all
select date,sval from
(select date,SUBSTRING_INDEX(rplace, ' ', 1)fval,SUBSTRING_INDEX(MID(rplace,8,LENGTH(rplace)), ' ', 1)sval,SUBSTRING_INDEX(MID(rplace,15,LENGTH(rplace)), ' ', 1)tval from
(select id, date, valuelist,REPLACE(valuelist,'|',' ') as rplace from
(select 1 as id, '2017-01-01' as date, 'value1|value2|value3' as valuelist union all
select 2, '2017-01-01', 'value1|value2' union all
select 3, '2017-01-01', 'value1') as a)as a) as a
UNION all
select date,tval from
(select date,SUBSTRING_INDEX(rplace, ' ', 1)fval,SUBSTRING_INDEX(MID(rplace,8,LENGTH(rplace)), ' ', 1)sval,SUBSTRING_INDEX(MID(rplace,15,LENGTH(rplace)), ' ', 1)tval from
(select id, date, valuelist,REPLACE(valuelist,'|',' ') as rplace from
(select 1 as id, '2017-01-01' as date, 'value1|value2|value3' as valuelist union all
select 2, '2017-01-01', 'value1|value2' union all
select 3, '2017-01-01', 'value1') as a)as a) as a) as a
where fval !='' GROUP BY fval,date
final Query:
SELECT date,fval as allValue,count(fval) as ValueCount from
(select date,fval from
(select date,SUBSTRING_INDEX(rplace, ' ', 1)fval,SUBSTRING_INDEX(MID(rplace,8,LENGTH(rplace)), ' ', 1)sval,SUBSTRING_INDEX(MID(rplace,15,LENGTH(rplace)), ' ', 1)tval from
(select id, date, valuelist,REPLACE(valuelist,'|',' ') as rplace from
(select * from yourTable) as a)as a) as a
union all
select date,sval from
(select date,SUBSTRING_INDEX(rplace, ' ', 1)fval,SUBSTRING_INDEX(MID(rplace,8,LENGTH(rplace)), ' ', 1)sval,SUBSTRING_INDEX(MID(rplace,15,LENGTH(rplace)), ' ', 1)tval from
(select id, date, valuelist,REPLACE(valuelist,'|',' ') as rplace from
(select * from yourTable as a)as a) as a
UNION all
select date,tval from
(select date,SUBSTRING_INDEX(rplace, ' ', 1)fval,SUBSTRING_INDEX(MID(rplace,8,LENGTH(rplace)), ' ', 1)sval,SUBSTRING_INDEX(MID(rplace,15,LENGTH(rplace)), ' ', 1)tval from
(select id, date, valuelist,REPLACE(valuelist,'|',' ') as rplace from
(select * from yourTable) as a)as a) as a) as a
where fval !='' GROUP BY fval,date
Result:
2017-01-01 value1 3
2017-01-01 value2 2
2017-01-01 value3 1
List the customer first name, last name, and total amount spent (Note: the amount spent is the order subtotal + the tax + the cost to ship from the tblorder table).
i have this code(but the values all come out the same:
Select CONCAT(firstname, ' ' ,lastname) as name, sum(ordersubtotal + ordertax + ordershipcost) as AmountSpent
From tblorder,tblcust
group by name
This should do it:
Select CONCAT(firstname, ' ' ,lastname) as name, sum(ordersubtotal + ordertax + ordershipcost) as AmountSpent
From tblorder a
inner join tblcust b ON a.custId=b.custId
group by name;
YOu did not define on what you are joining the tables.
In your code style that would be:
Select CONCAT(firstname, ' ' ,lastname) as name, sum(ordersubtotal + ordertax + ordershipcost) as AmountSpent
From tblorder a,tblcust b
where a.custId=b.custId
group by name;
(Both should give the same result)
[I have gone through a large number of questions before posting this question.]
I have a table which contains 4 fields. It is ClientId, ClientName,ClientAddress, ClientCity.
Now, I have an autocomplete textbox control where I need to fetch & display client name.
The problem is that in our database we have same client from the same city from different address.
Now the requirement given to me is that the user should be able to see "ClientName" or "ClientName + ClientCity" or "ClientName+ClientCity+ClientAddress" to make it easy for user to select the client.
It means that I need to add a column to the query till it makes it unique.
I am sure there must be some simple solution to this which I am not getting for past 2 days now.
As shown in below sample data, If I show only "D" as a client name to the end user, he will be confused as in which client "D" he has to select. So we need to concatenate city and address to make it unique.
I am expecting an output as below.
You can use COUNT() OVER() for this:
;WITH CTE AS(
SELECT *,
ByName = COUNT(*) OVER(PARTITION BY ClientName),
ByCity = COUNT(*) OVER(PARTITION BY ClientName,ClientCity)
FROM Client
)
SELECT
CASE
WHEN ByName = 1 AND ByCity = 1 THEN ClientName
WHEN ByName > 1 AND ByCity = 1 THEN ClientName + ', ' + ClientCity
WHEN ByName > 1 AND ByCity > 1 THEN ClientName + ', ' + ClientCity + ', ' + ClientAddress
END
FROM CTE
ORDER BY ClientID
RESULT
Client
--------------------------------------------------------
A
B
C, New York
D, London, LSE Houghton Streen London WC2A 2AE
D, London, Hard Rock Cafe London 150 Old Park Lane
F
C, Paris
See SQL Fiddle.
If you are using SQL Server, you can try the string concatenation using "+" operator as follows
select
ClientName + ', ' + ClientCity + ', ' + ClientAddress as ClientData,
Concat(ClientName, ', ', ClientCity, ', ', ClientAddress) Client
from client
The second concatenation is built using SQL CONCAT() funtion will work on SQL Server 2012 and later
For the conditional data following SELECT statement can help,
select
-- ClientName + ', ' + ClientCity + ', ' + ClientAddress as ClientData,
-- Concat(ClientName, ', ', ClientCity, ', ', ClientAddress) ClientDtata2,
client =
case when count(*) over (partition by ClientName) = 1 then ClientName
else
case when count(*) over (partition by ClientName, ClientCity) = 1 then CONCAT(ClientName, ', ' , ClientCity)
else Concat(ClientName, ', ', ClientCity, ', ', ClientAddress)
end
end
from client
TRY THIS,
Declare #t table (clientid int identity(1,1),clientname varchar(50),clientCITY varchar(50)
,clientaddress varchar(200))
insert into #t values ('A','PARIS','DFSDFSDF'), ('C','NEW YORK','DFSDFSDF')
,('C','PARIS','WEQWEQWE'),('D','LONDON','QWE342'),('D','LONDON','21DXCXZC')
;With CTE as
(select *,ROW_NUMBER()over(partition by clientname order by clientid)rn
,ROW_NUMBER()over(partition by clientname,ClientCity order by clientid)rn1
from #T A
)
--select * from cte
select clientname+','+ clientCITY
from cte A WHERE
EXISTS(SELECT CLIENTID FROM CTE WHERE clientname=A.clientname AND RN>1 AND RN1<=1)
UNION ALL
select clientname+','+ clientaddress
from cte A WHERE
EXISTS(SELECT CLIENTID FROM CTE WHERE clientname=A.clientname AND RN1>1)
UNION ALL
select clientname
from cte A WHERE not
EXISTS (SELECT CLIENTID FROM CTE WHERE clientname=A.clientname AND RN>1 )