Incident Table
I have Incident Table like below i need to match the client list in client table. How can i do that in oracle ?
INCIDENT_ID |CLIENTS_LIST |
------------|-----------------|
56 |A001##A05M##A0AS |
Client Table
BO_NAME |COMPANYID
----------------------|---------
Test1 |A001
Test2 |A0AS
Test3 |A05M
Test4 |A0BT
Im trying to match the companyid with clients_list but there is no result.
Tried Query
SELECT DISTINCT INCIDENT_ID,
CLIENTS_LIST,
REPLACE(CLIENTS_LIST, '##', ',') AS client_id,
cl.BO_NAME,
COMPANYID
FROM incident ir
INNER JOIN Client cl
ON cl.companyid IN (REPLACE(CLIENTS_LIST, '##', ','))
Expected Output
BO_NAME |COMPANYID
----------------------|---------
Test1 |A001
Test2 |A0AS
Test3 |A05M
I see a design problem there, you should always save each value in a separate column, or in a separate table with a 1-to-many relationship.
Now, you aren't going to make an efficient query, or at least, as efficient as it could be. With that in mind, you could use LIKE Operator in combination with CROSS JOIN This query is very unnefficient, but it should work:
SELECT *
FROM incidentTable t, clientTable c
WHERE t.IncidentId = 56 AND '#' || t.ClientList || '#' LIKE '%#' || c.CompanyId || '#%'
you can use oracle instr
with inc(INCIDENT_ID,CLIENTS_LIST) as (select 56, 'A001##A05M##A0AS' from dual),
Client(BO_NAME,COMPANYID) as
(select 'Test1','A001' from dual union all
select 'Test2','A0AS' from dual union all
select 'Test3','A05M' from dual union all
select 'Test4','A0BT' from dual )
select *
from inc, client
where instr(clients_list,companyid) > 0
INCIDENT_ID CLIENTS_LIST BO_NAME COMPANYID
----------- ---------------- ------- ---------
56 A001##A05M##A0AS Test1 A001
56 A001##A05M##A0AS Test2 A0AS
56 A001##A05M##A0AS Test3 A05M
Related
Helo every one! I tried to find solution on the previous asked questions from the site but I find none of them related with mine, I need help on how to select seven scored marks between nine on the same row in a table which have HIGH SCORE and SUM them as shown below.
name | math | geography | history | pds | ict | civics | social | vskil | french
Joseph 100 90 80 84 70 40 70 90 70
So here the following seven (7) marks supposed to be chosen (100 + 90 + 80 + 84 + 70 + 90 + 70).
Any help please.
You need to convert columns into rows and then make your select
You can try this query
select sum(grade) from (
(select math as 'grade' from table1 where name = 'Joseph')
union all
(select geography from table1 where name = 'Joseph')
union all
(select history from table1 where name = 'Joseph')
union all
(select pds from table1 where name = 'Joseph')
union all
(select ict from table1 where name = 'Joseph')
union all
(select civics from table1 where name = 'Joseph')
union all
(select social from table1 where name = 'Joseph')
union all
(select vskil from table1 where name = 'Joseph')
union all
(select french from table1 where name = 'Joseph')
) as x
order by grade desc
limit 7
You can get better performance, use less storage and make code easier to write with the following table structure instead of the current one.
Table students:
id integer primary key
name varchar
Table subjects
studentid integer primary key references students(id)
subject varchar
marks int
Real optimation would mean a subjects table and a subject marks table. Please read up on database normalization for details.
With this structure for a given student,
SELECT SUM(marks)
FROM (SELECT marks FROM subjects WHERE studentid=some_number ORDER BY marks DESC limit 7) AS a
Gives the marks for the top 7 subjets for a given student.
I try to select all from 2 tables in mysql database with the sum of total cost in the second table
i have a table name tbl_project contain
db_id db_projectname and other column
1 test
2 test2
3 test3
second table name tbl_activities contain
db_id db_projectname db_totalcost
1 test 200
2 test 300
3 test2 800
the out put i want is
test 500
test2 800
test3
i try this query but it didn't give me that result
select tbl_project.db_id, tbl_project.db_projectname,tbl_project.db_location,tbl_project.db_client,tbl_project.db_transferredto,tbl_project.db_psd,tbl_project.db_pdd,tbl_project.db_duration,tbl_project.db_past,tbl_project.db_padd,tbl_project.db_aduration,tbl_project.db_percent,tbl_project.db_pnote,tbl_project.db_user,tbl_project.db_cpercentage,tbl_project.db_epercentage,tbl_project.db_mpercentage,tbl_project.db_status,tbl_project.db_offer,tbl_project.db_sheet,tbl_project.db_invoice,tbl_project.db_po,sum(tbl_activities.db_totalcost) as total_cost from tbl_project,tbl_activities where
tbl_project.db_projectname=tbl_activities.db_projectname
it give me
test but sum of another project and only one project not all
You needed to use LEFT JOIN & GROUP BY
SELECT
tbl_project.db_id,
tbl_project.db_projectname,
tbl_project.db_location,
tbl_project.db_client,
tbl_project.db_transferredto,
tbl_project.db_psd,
tbl_project.db_pdd,
tbl_project.db_duration,
tbl_project.db_past,
tbl_project.db_padd,
tbl_project.db_aduration,
tbl_project.db_percent,
tbl_project.db_pnote,
tbl_project.db_user,
tbl_project.db_cpercentage,
tbl_project.db_epercentage,
tbl_project.db_mpercentage,
tbl_project.db_status,
tbl_project.db_offer,
tbl_project.db_sheet,
tbl_project.db_invoice,
tbl_project.db_po,
sum(
tbl_activities.db_totalcost
) AS total_cost
FROM
tbl_project
LEFT JOIN tbl_activities ON tbl_project.db_projectname = tbl_activities.db_projectname
GROUP BY tbl_project.db_id
Note:
Using aggregate function (e.g. SUM,COUNT..) without GROUP BY collapses the result set into a single row.
try this;
SELECT
db_projectname.db_projectname,SUM(tbl_activities.db_totalcost) AS total_cost
FROM db_projectname
LEFT JOIN tbl_activities
ON
db_projectname.db_projectname = tbl_activities.db_projectname
GROUP BY db_projectname.db_projectname
Essentially, I have a table that is like this:
FirstName, LastName, Type
Mark, Jones, A
Jim, Smith, B
Joseph, Miller, A
Jim, Smith, A
Jim, Smith, C
Mark, Jones, C
What I need to do is be able to display these out in PHP/HTML, like:
Name | Total Count Per Name | All Type(s) Per Name
which would look like...
Mark Jones | 2 | A, C
Jim Smith | 3 | B, A, C
Joseph Miller | 1 | A
Jim Smith | 3 | B, A, C
Jim Smith | 3 | B, A, C
Mark Jones | 2 | A, C
I have spent time trying to create a new table based off the initial one, adding these fields, as well as looking at group_concat, array_count_values, COUNT, and DISTINCT, along with other loop/array options, and cannot figure this out.
I've found a number of answers that count and concatenate, but the problem here is I need to display each row with the total count/concatenation on each, instead of shortening it.
How about doing it like this?
SELECT aggregated.* FROM table_name t
LEFT JOIN (
SELECT
CONCAT(FirstName, ' ', LastName) AS Name,
COUNT(Type) AS `Total Count Per Name`,
GROUP_CONCAT(Type SEPARATOR ',') AS `All Type(s) Per Name`
FROM table_name
GROUP BY Name) AS aggregated
ON CONCAT(t.FirstName, ' ', t.LastName) = aggregated.Name
Without an ORDER BY clause, the order the rows will be returned in is indeterminate. Nothing wrong with that, by my personal preference is to have the result to be repeatable.
We can use an "inline view" (MySQL calls it a derived table) to get the count and the concatenation of the Type values for (FirstName,LastName).
And then perform a join operation to match the rows from the inline view to each row in the detail table.
SELECT CONCAT(d.FirstName,' ',d.LastName) AS name
, c.total_coount_per_name
, c.all_types_per_name
FROM mytable d
JOIN ( SELECT b.FirstName
, b.LastName
, GROUP_CONCAT(DISTINCT b.Type ORDER BY b.Type) AS all_types_per_name
, COUNT(*) AS total_count_per_name
FROM mytable b
GROUP
BY b.FirstName
, b.LastName
) c
ON c.FirstName = d.FirstName
AND c.Last_name = d.LastName
ORDER BY d.FirstName, d.LastName
If you have an id column or some other "sequence" column, you can use that to specify the order the rows are to be returned; same thing in the GROUP_CONCAT function. You can omit the DISTINCT keyword from the GROUP_CONCAT if you want repeated values... 'B,A,B,B,C',
In my table 1 I have something like this
name | age
George 42
Bob 30
Ken 23
In my table 2, I have something like this, this is where i store votes for each person.
name | votes |
George 1
Ken 1
George 1
George 1
Ken 1
My goal is to combine the 2 tables, and return all the rows in table 1 even it doesn't exist in table 2.
Desire results:
name | age | total_votes
George 42 3
Bob 30 0
Ken 23 2
But instead I get:
name | age | total_votes
George 42 3
Ken 23 2
I have tried something like this
SELECT `table_1`.*, coalesce(COUNT(`table_2`.votes), 0) AS total_votes
FROM `table_1`
LEFT JOIN `table_2`
ON `table_1`.name = `table_2`.name
You can do one of these:
1) Use Right Join instead of current Left Join.
Or
2) Exchange table1 and table2 places in your join expression, like:
FROM table_2
LEFT JOIN table_1
Try this. This works in MS Access , I think this will work on your's too just convert the query to SQL:
SELECT Table1.name, First(Table1.age) AS age, Count(Table2.Votes) AS totalVotes
FROM Table1 LEFT JOIN Table2 ON Table1.name = Table2.name
GROUP BY Table1.name;
Left Join table1 to table2 so that all entry from table1 , even if its is corresponding data is null, will be included. GROUP BY your query by name so that votes will be counted by name .
I have several tables with different numbers and types of columns, and a single column in common.
+--------+---------+------------+-------------+
| person | beardID | beardStyle | beardLength |
+--------+---------+------------+-------------+
+--------+-------------+----------------+
| person | moustacheID | moustacheStyle |
+--------+-------------+----------------+
I want to fetch all the results that match a given value of the shared column. I can do it using multiple select statements like this:
SELECT * FROM beards WHERE person = "bob"
and
SELECT * FROM moustaches WHERE person = "bob"
But this requires multiple mysql API calls, which seems inefficient. I was hoping I could use UNION ALL to get all the results in a single API call, but UNION requires that the tables have the same number and similar type of columns. I could write a SELECT statement that would manually pad the results from each table by adding columns with NULL values, but that would quickly get unmanageable for a few more tables with a few more columns.
I'm looking for a result set roughly like this:
+--------+---------+------------+-------------+-------------+----------------+
| person | beardID | beardStyle | beardLength | moustacheID | moustacheStyle |
+--------+---------+------------+-------------+-------------+----------------+
| bob | 1 | rasputin | 1 | | |
+--------+---------+------------+-------------+-------------+----------------+
| bob | 2 | samson | 12 | | |
+--------+---------+------------+-------------+-------------+----------------+
| bob | | | | 1 | fu manchu |
+--------+---------+------------+-------------+-------------+----------------+
Is there a way to achieve this that's fast and maintainable? Or am I better off running a separate query for each table?
Clarification:
I'm not looking for a cartesian product. I don't want a row for every combination of beard-and-moustache, I want a row for every beard and a row for every moustache.
So if there are 3 matching beards and 2 matching moustaches I should get 5 rows, not 6.
this should be working fine:
SELECT * FROM `beards` b LEFT OUTER JOIN `mustaches` ON (0) WHERE person = "bob"
UNION ALL
SELECT * FROM `beards` b RIGHT OUTER JOIN `mustaches` ON (0) WHERE person = "bob"
you don't have to handle the columns by yourself. the left and right outer join do this job.
unfortunately mysql doesn't have a full join. that's why you have to do it this way with a union
SELECT * FROM `customer` b LEFT OUTER JOIN `charges` ON (0) LEFT OUTER JOIN `day` ON (0)
UNION
SELECT * FROM `customer` b RIGHT OUTER JOIN `charges` ON (0) LEFT OUTER JOIN `day` ON (0)
UNION
SELECT * FROM `customer` b LEFT OUTER JOIN `charges` ON (0) RIGHT OUTER JOIN `day` ON (0)
this is a local test i made
Join on person....
I.e.
Select
t1.(asterix), t2.(asterix)
FROM
beards t1
INNER JOIN
moustaches t2 On t2.person = t1.person
SELECT *
FROM beards
JOIN moustaches
ON moustaches.person = beards.person
WHERE person = "bob"
I had fun with this, not sure it's entirely manageable with what more you have to add, but it accomplished the goal.
create table beard (
person varchar(20)
,beardID int
,beardStyle varchar(20)
,beardLength int )
create table moustache(
person varchar(20)
,moustacheID int
,moustacheStyle varchar(20))
insert into beard
select 'bob', 1, 'rasputin', 1
union select 'bob', 2, 'samson', 12
insert into moustache
select 'bob', 1, 'fu manchu'
declare #facialhair table (
person varchar(20)
,beardID int
,beardStyle varchar(20)
,beardLength int
,moustacheID int
,moustacheStyle varchar(20))
declare #i int
declare #name varchar(20)
set #name = 'bob'
set #i = (select COUNT(*) from beard where person = #name)
+ (select COUNT(*) from moustache where person = #name)
print #i
while #i > 0
begin
insert into #facialhair (person, beardID, beardStyle, beardLength)
select person, beardID, beardStyle, beardLength
from beard
where person = #name
set #i = #i-##ROWCOUNT
insert into #facialhair (person, moustacheID, moustacheStyle)
select person, moustacheID, moustacheStyle
from moustache
where person = #name
set #i = #i-##ROWCOUNT
end
select *
from #facialhair
I think you would be better by making queries for data in each table.
One of other possibilities is to concatenate data from all columns into one big string (you could choose some sign to separete column's values), then you should be able to use union all clause to combine results from each query - but then you will have to parse each row.. And data types will be lost.