List of users in a JIRA Project - sql

Can someone please help me with a SQL to retrieve users associated to a JIRA project?

SELECT A.ROLETYPEPARAMETER AS USERNAME, R.NAME AS ROLENAME, P.PKEY || ' - ' || P.PNAME AS PROJECTNAME
FROM PROJECTROLEACTOR A
INNER JOIN PROJECTROLE R ON A.PROJECTROLEID = R.ID
INNER JOIN PROJECT P ON A.PID = P.ID
ORDER BY 3, 1, 2;
or to just aggregate the users per project:
SELECT DISTINCT P.PKEY, LISTAGG(A.ROLETYPEPARAMETER, ',') WITHIN GROUP(ORDER BY A.ROLETYPEPARAMETER ASC) OVER(PARTITION BY P.PKEY) AS USERNAMES
FROM PROJECTROLEACTOR A
INNER JOIN PROJECTROLE R ON A.PROJECTROLEID = R.ID
INNER JOIN PROJECT P ON A.PID = P.ID
GROUP BY P.PKEY, A.ROLETYPEPARAMETER;;

For Jira 6, the correct MySQL syntax is:
SELECT
A.ROLETYPEPARAMETER AS USERNAME,
R.NAME AS ROLENAME, CONCAT(P.pkey, ' - ', P.pname) AS PROJECTNAME
FROM projectroleactor A
INNER JOIN projectrole R ON A.PROJECTROLEID = R.ID
INNER JOIN project P ON A.PID = P.ID
ORDER BY 3, 1, 2
NOTE: field names are case-sensitive

Related

Postgres: what's wrong with the syntax of this query?

I'm trying to write a fairly straightforward PSQL query to retrieve some data (I realise it's not the most efficient query right now):
SELECT c.name AS article, c.id AS article_id, t.name AS template, t.id AS template_id, brand_names, COUNT(p.component_id)
FROM publications p
INNER JOIN components c
(SELECT string_agg(b.name, ', ') AS brand_names
FROM brands b
INNER JOIN brands_components
ON b.id = brands_components.brand_id
WHERE brands_components.component_id = c.id
) brand_query
ON c.id = p.component_id
INNER JOIN brands_components bc
ON c.id = bc.component_id
AND bc.brand_id IN (16, 23, 24, 35, 37)
INNER JOIN components_templates ct
ON c.id = ct.component_id
INNER JOIN templates t
ON t.id = ct.template_id
This gives me a syntax error though on line 4. What's missing? If I run the subquery alone it works fine:
syntax error at or near "SELECT" LINE 4: (SELECT string_agg(b.name, ', ') AS brand_names ^ : SELECT c.name AS article, c.id AS article_id, t.name AS template, t.id AS template_id, brand_nam
The subquery is designed to retrieve all the brand names per component and display them in a single row instead of many. Their join table is brands_components.
A fiddle that is available here, the desired result should be something like:
article article_id template template_id count brands
--------------------------------------------------------------------------------------------------------------
component one | 1 | template one | 1 | 4 | brand one, brand two, brand three, brand four
Your immediate problem could be solved with a a lateral join:
SELECT c.name AS article, c.id AS article_id, t.name AS template, t.id AS template_id, brand_names, COUNT(p.component_id)
FROM publications p
JOIN components c ON c.id = p.component_id
JOIN brands_components bc ON c.id = bc.component_id AND bc.brand_id IN (1, 2, 3, 4)
JOIN LATERAL (
SELECT b.id, string_agg(b.name, ', ') AS brand_names
FROM brands b
JOIN brands_components ON b.id = brands_components.brand_id
WHERE brands_components.component_id = c.id
GROUP BY b.id
) brand_query ON brand_query.id = bc.brand_id
JOIN components_templates ct ON c.id = ct.component_id
JOIN templates t ON t.id = ct.template_id
GROUP BY 1,2,3,4
The above would still not run because the group by doesn't include the brand_names column. Postgres doesn't know that brand_names is already aggregates.
However, the derived table is not really needed if you move the aggregation to the outer query:
SELECT c.name AS article,
c.id AS article_id,
t.name AS template,
t.id AS template_id,
string_agg(b.name, ',') as brand_names,
COUNT(p.component_id)
FROM publications p
JOIN components c ON c.id = p.component_id
JOIN brands_components bc ON c.id = bc.component_id AND bc.brand_id IN (1, 2, 3, 4)
JOIN brands b on b.id = bc.brand_id
JOIN components_templates ct ON c.id = ct.component_id
JOIN templates t ON t.id = ct.template_id
GROUP BY c.name, c.id, t.name, t.id;
Try this Query:
SELECT c.name AS article, c.id AS article_id, t.name AS template, t.id AS template_id,MAX(brand_names) AS brand_names, COUNT(p.component_id) AS Counts
FROM publications p
INNER JOIN components c
ON c.id = p.component_id
INNER JOIN brands_components bc
ON c.id = bc.component_id
AND bc.brand_id IN (1, 2, 3, 4)
INNER JOIN components_templates ct
ON c.id = ct.component_id
INNER JOIN templates t
ON t.id = ct.template_id
INNER JOIN (SELECT string_agg(b.name, ', ') AS brand_names
FROM brands b
INNER JOIN brands_components bcc
ON b.id = bcc.brand_id
INNER JOIN components c ON bcc.component_id = c.id
) brand_query ON brand_names IS NOT NULL
Group by c.name,c.id,t.name,t.id
I got it working with a function:
CREATE FUNCTION brands(int) RETURNS varchar AS $$
SELECT string_agg(b.name, ', ') AS brand_names
FROM brands b
INNER JOIN brands_components
ON b.id = brands_components.brand_id
WHERE brands_components.component_id = $1
$$ LANGUAGE SQL;
SELECT c.name, c.id, t.name AS template_name, t.id AS template_id, brands(c.id), COUNT(p.component_id)
FROM publications p
INNER JOIN components c
ON c.id = p.component_id
INNER JOIN brands_components bc
ON c.id = bc.component_id
AND bc.brand_id IN (1, 2, 3, 4)
INNER JOIN components_templates ct
ON c.id = ct.component_id
INNER JOIN templates t
ON t.id = ct.template_id
GROUP BY 1, 2, 3, 4
Not sure which is preferable, likely it's DineshDB's though.

Error in on clause comparison - Big Query

The following big query code gives the following error.
select
selected_date date,
pp.name property,
bb.bookings bb,
av.available vailable,
from
(SELECT DATE(DATE_ADD(TIMESTAMP("2017-10-01"), pos - 1, "DAY")) AS selected_date
FROM (
SELECT ROW_NUMBER() OVER() AS pos, *
FROM (FLATTEN((
SELECT SPLIT(RPAD('', 1 + DATEDIFF(TIMESTAMP(CURRENT_DATE()), TIMESTAMP("2017-10-01")), '.'),'') AS h
FROM (SELECT NULL)),h
)))) v
cross join
(select p.name name from [roomsproperties.properties] p where p.name not like '%test%' group by name) as pp
left join
(select sum(b.rooms) bookings,
p.name property,
b.checkin checkin,
b.checkout checkout
from [bookings.bookings] b
left join [roomsproperties.rooms] r on r.id = b.room_id
left join [roomsproperties.properties] p on p.id = r.property_id
where p.name not like '%test%'
and b.status not in('Rejected', 'Cancelled - By customer', 'OTP Not Varified')
group by property,checkin,checkout
) as bb on pp.name = bb.property and (v.selected_date between bb.checkin and bb.checkout)
left join
(select sum(r.quantity) available,
p.name property,
date(r.created_at) date
from [roomsproperties.rooms] r
left join [roomsproperties.properties] p on p.id = r.property_id
group by property, date
) av on pp.name = av.property and v.selected_date >= av.date
The error is,
Error: ON clause must be AND of = comparisons of one field name from each table, with all field names prefixed with table name. Consider using Standard SQL
Can any one help
You should try:
(select ...) as bb on pp.name = bb.property
WHERE v.selected_date between bb.checkin and bb.checkou
and:
(select ...) as av on pp.name = av.property
WHERE v.selected_date >= av.date

Too many results in query

I'm fetching some data from our database in MSSQL. Out of this data I want to determine who created the client entry and who took the first payment from this client.
There can be many payment entries for a client on a single booking/enquiry and at the moment, my query shows results for each payment. How can I limit the output to only show the first payment entry?
My query:
SELECT
c.FirstName,
c.LastName,
c.PostalCode,
o.OriginOfEnquiry,
s.SuperOriginName,
c.DateOfCreation,
DATEDIFF(day, c.DateOfCreation, p.DateOfCreation) AS DaysToPayment,
pc.PackageName,
CONCAT(u.FirstName, ' ', u.LastName) AS CreateUser,
(SELECT CONCAT(u.FirstName, ' ', u.LastName)
WHERE u.UserID = p.UserID ) AS PaymentUser
FROM tblBookings b
INNER JOIN tblPayments p
ON b.BookingID = p.BookingID
INNER JOIN tblEnquiries e
ON e.EnquiryID = b.EnquiryID
INNER JOIN tblCustomers c
ON c.CustomerID = e.CustomerID
INNER JOIN tblOrigins o
ON o.OriginID = e.OriginID
INNER JOIN tblSuperOrigins s
ON s.SuperOriginID = o.SuperOriginID
INNER JOIN tblBookingPackages bp
ON bp.bookingID = p.BookingID
INNER JOIN tblPackages pc
ON pc.PackageID = bp.packageID
INNER JOIN tblUsers u
ON u.UserID = c.UserID
WHERE c.DateOfCreation >= '2016-06-01' AND c.DateOfCreation < '2016-06-30'
AND p.PaymentStatusID IN (1,2)
AND e.CustomerID = c.CustomerID
AND p.DeleteMark != 1
AND c.DeleteMark != 1
AND b.DeleteMark != 1
;
I tried adding a "TOP 1" to the nested select statement for PaymentUser, but it made no difference.
you can use cross apply with top 1:
FROM tblBookings b
cross apply
(select top 1 * from tblPayments p where b.BookingID = p.BookingID) as p
Instead of table tblPayments specify sub-query like this:
(SELECT TOP 1 BookingID, UserID, DateOfCreation
FROM tblPayments
WHERE DeleteMark != 1
AND PaymentStatusID IN (1,2)
ORDER BY DateOfCreation) as p
I'm assuming that tblPayments has a primary key column ID. If it is true, you can use this statment:
FROM tblBookings b
INNER JOIN tblPayments p ON p.ID = (
SELECT TOP 1 ID
FROM tblPayments
WHERE BookingID = b.BookingID
AND DeleteMark != 1
AND PaymentStatusID IN (1,2)
ORDER BY DateOfCreation)

select user doesn't contain a record in other table sql query

I had three tables: sarcuser, sarcusercommittee, sarcallcourse. I need to build a query that brings all the users that don't have a committee (they don't have a record in sarcusercommittee). Here is my current query:
SELECT u.firstname + ' ' + u.lastname AS name, u.dateofbirth, u.gender, LEFT(u.note, 200) AS note, c.name AS coursename
FROM sarcuser AS u INNER JOIN
sarcusercommittee AS uc ON u.id = uc.user_id INNER JOIN
sarcallcourse AS c ON c.id = u.courseid
WHERE ((SELECT COUNT(id) AS Expr1
FROM sarcusercommittee
WHERE (user_id = u.id)) = 0)
ORDER BY name DESC
I guess the problem is in (ON condistion) but don't get it ... any help ?
NOTE : I use visual studio 2010
SELECT u.firstname + ' ' + u.lastname AS name, u.dateofbirth, u.gender, LEFT(u.note, 200) AS note, c.name AS coursename
FROM sarcuser AS u
INNER JOIN sarcallcourse AS c
ON c.id = u.courseid
WHERE u.id NOT IN (
SELECT uc.user_id
FROM sarcusercommittee AS uc
)
ORDER BY name DESC
Firstly you shouldn't inner join onto sarcusercommittee if you dont want rows from it. Seconly I would filter to the users that are not in sarcusercommittee using NOT IN.

SQL - Multiple table join and select first record on conditions

I Have the following tables:
Projects (ID, Name, ManagerUser_ID)
Users(ID, Name, Active)
Delegates(ProjectID, UserID, OrderNo)
The ManagerUser_ID is the Project Manager for the project and is a link to the users table. Users, however can be Inactive. So, the Delegates table is a many to many table defining Users that can access the project data.
What i require, is to select the first Delegate for a project that is Active assuming the manager is Inactive. The OrderNo field specifies the order of the delegates (1 being first).
Some sample data:
Project
1, Project1, 2
2, Project2, 4
3, Project3, 1
Users
1, Joe, true
2, John, false
3, Dave, true
4, Bob, false
Delegates
1, 4, 1
1, 1, 2
1, 3, 3
2, 2, 1
2, 4, 2
2, 3, 3
So the output of my query would need to show:
Project1, Joe
Project2, Dave
Project3, Joe
Show Projects and Users for each project where if the ManagerUser_ID is inactive, then Select the User in Delegates with the lowest OrderNo that is Active.
This seems to do the trick (using window function)
SELECT P.Name, ISNULL(U.Name, FirstDelegate.Name) AS ProjManager
FROM Projects P LEFT OUTER JOIN
Users U ON P.ManagerUser_ID = U.ID AND U.Active = 1 LEFT OUTER JOIN
(
SELECT * FROM
(
SELECT D.ProjectID,
US.Name,
ROW_NUMBER() OVER (PARTITION BY ProjectID ORDER BY OrderNo) AS SeqNo
FROM Delegates D INNER JOIN
Users US ON D.UserID = US.ID
WHERE US.Active = 1
) AS Del
WHERE Del.SeqNo = 1
) AS FirstDelegate ON P.ID = FirstDelegate.ProjectID
Select projectName, userName
From
(
Select projectName, userName, row_number() over (partition by projectName order by priority ASC) as rank
From
(
SELECT p.name as projectName, u.name as userName, 1 as priority
FROM projects p INNER JOIN users u ON u.active = true and u.id = p.ManagerUser_ID
UNION
SELECT TOP(1) p.name, u.name, 2
FROM Delegates d INNER JOIN projects p ON p.id = d.projectId
INNER JOIN users u ON u.id = d.userId
Where u.active = true
Order by u.OrderNo ASC
)
)
where rank = 1
I think it's going to be something like this. The idea is to do an extra join (using left join) to find an earlier valid row. If you can find that row, then obviously the current row you're constructing isn't one that you want:
select p.Name,m.Name from Projects p inner join Users m on p.ManagerUser_ID = m.ID and m.Active = 1
union all
select
p.Name,
u.Name
from
Projects p
inner join
Delegates d
on
p.ID = d.ProjectID
inner join
Users u
on
d.UserID = u.ID and
u.Active = 1
left join
Delegates d_anti
inner join
Users u_anti
on
d_anti.UserID = u_anti.ID and
u_anti.Active = 1
on
p.ID = d_anti.ProjectID and
d_anti.OrderNo < d.OrderNo
where
u_anti.ID is null
select p.name,
u.name,
min(d.orderNo)
from projects p,
users u,
users manager,
delegates d
where p.ManagerUser_ID = manager.id
and manager.active = false
and p.id = d.projectId
and d.userid = u.id
group by p.name,
u.name