Use case statement in where clause conditional to brings data according to user level - oracle11g

I am trying to create a query that brings me data according to user level and user id.
In my query, Level 1 is Administrator and can see everything, but other users can only see their records.
As i wrote this query works only for other users and not for Administrators.
If my LEVEL_TYPE = 1 then get all rows,
elsif my LEVEL_TYPE 1 then get all rows for this USER_ID.
SELECT cl.ID as ID,
cl.FIRST_NAME || ' ' || cl.LAST_NAME as PATIENT,
cl.AGE as AGE,
CASE
when cl.SEX ='M' then 'Άντρας' when cl.SEX ='F' then 'Γυναίκα'
when cl.SEX ='O' then 'Άλλο' when cl.SEX ='C' then 'Ζευγάρι' END as SEX,
sa.SESSION_AREA as SESSION_AREA,
ms.MARITAL_KIND as MARITAL_KIND,
wt.WORK_KIND as WORK_KIND,
ph.PATIENT_PHOTO as PATIENT_PHOTO,
case when cl.ACTIVE = 1 then 'ΕΝΕΡΓΟΣ'
when cl.ACTIVE = 2 then 'ΑΝΕΝΕΡΓΟΣ' end as PATIENT_ACTIVE,
pt.PAYMENT_KIND as PAYMENT_KIND
FROM CLIENTS cl
left join PAYMENT_TYPE pt on pt.ID = cl.PATIENT_TYPE
left join WORK_TYPE wt on wt.ID = cl.WORKING_CONDITION
left join MARITAL_STATUS ms on ms.ID = cl.MARITAL_STATUS
left join SESSIONS_AREA sa on sa.ID = cl.SESSION_AREA
left outer join PHOTOS ph on ph.CLIENTS_ID = cl.ID
inner join USER_PATIENTS up ON up.PATIENT_ID = cl.ID
inner join APP_USERS au on au.ID = up.USER_ID
WHERE (au.LEVEL_TYPE = 1) or
(au.LEVEL_TYPE <> 1 and up.USER_ID = (SELECT au.id
FROM APP_USERS au
WHERE au.APEX_ID = APEX_UTIL.GET_CURRENT_USER_ID))
ORDER BY cl.ACTIVE, cl.FIRST_NAME || ' ' || cl.LAST_NAME

Related

Use check box selected elements to filter report

I have an issue with making a correct report for my application. The report is supposed to return free rooms for a set of parameters (including a list of equipements). However, I cannot include the equipements search in my interractive report.
Here is the SQL request I've got:
SELECT s.code || ' ' || s.nom as Salle, s.capacite, LISTAGG(eq.libelle, ', ') WITHIN GROUP (ORDER BY eq.code) as Equipements, b.libelle as Batiment, s.numero
FROM SALLES s
INNER JOIN batiments b ON
b.numero = s.bat_numero
INNER JOIN sal_gpe sg ON
s.numero = sg.sal_numero
INNER JOIN groupespersonnes gp ON
gp.numero = sg.gpe_numero
LEFT JOIN equ_sal e ON
e.sal_numero = s.numero
LEFT JOIN equipements eq ON
eq.numero = e.equ_numero
-- On vérifie les salles visibles pour le groupe de personne affecté à l'utilisateur connecté.
WHERE gp.code = (SELECT code FROM groupespersonnes INNER JOIN personnes p ON p.gpe_numero = groupespersonnes.numero WHERE UPPER(:APP_USER) = UPPER(p.username))
AND :P30_PERIODE_DEBUT NOT IN (SELECT per_numero FROM enregistrements WHERE sal_numero = s.numero AND TO_CHAR(jour, 'DD.MM.RR') = :P30_DATE)
AND :P30_PERIODE_FIN NOT IN (SELECT per_numero FROM enregistrements WHERE sal_numero = s.numero AND TO_CHAR(jour, 'DD.MM.RR') = :P30_DATE)
AND e.equ_numero = regexp_substr(:P30_EQUIPEMENTS,'[^:]+')
GROUP BY s.capacite, s.nom, b.libelle, s.numero, s.code
I'm doing a LISTAGG on the equipements, so that I can show all the equipements for one room fit in one cell. Now :P30_EQUIPEMENT is actually a STRING. It takes the number of the equipements selected from the checkbox list (Dynamic LOV), and separates them with a ":". I've been trying many solutions but nothing worked. I'm now diving in the PL/SQL option.
If you have a idea of an easier way, I'd gladly take it.
If this is what :P30_EQUIPMENTS contains, then you should:
SQL> with test (p30_equipments) as
2 (select 'tv:balcony:shower' from dual)
3 select regexp_substr(p30_equipments, '[^:]+', 1, level) equipment
4 from test
5 connect by level <= regexp_count(p30_equipments, ':') + 1;
EQUIPMENT
-----------------
tv
balcony
shower
SQL>
i.e. applied to your code:
and e.equ_numero in (select regexp_substr(:p30_equipments, '[^:]+', 1, level)
from dual
connect by level <= regexp_count(:p30_equipments, ':') + 1
)

SQLite: CASE within FROM section

I need to select the MCUs table if UserID = 7 does not exist in the table. Please help me, what am I doing wrong?
SELECT
MCUs.MCUID
FROM
CASE
WHEN ReqMCUDevs.UserID = 7 THEN
MCUs
INNER JOIN MCUDevs
ON MCUs.MCUID = MCUDevs.MCUID
INNER JOIN ReqMCUDevs
ON MCUDevs.DevID = ReqMCUDevs.DevID
AND ReqMCUDevs.Quantity >= MCUDevs.Quantity
ELSE
MCUs
END
I need the resunt ot this query if UserID=7 exists
SELECT
MCUs.MCUID
FROM
MCUs
INNER JOIN MCUDevs
ON MCUs.MCUID = MCUDevs.MCUID
INNER JOIN ReqMCUDevs
ON MCUDevs.DevID = ReqMCUDevs.DevID
AND ReqMCUDevs.Quantity >= MCUDevs.Quantity
WHERE
ReqMCUDevs.UserID = 7
and this query if not
SELECT
MCUs.MCUID
FROM
MCUs
database schema:
The easiest solution is to use two different queries
db = sqlite3.connect("..\\DB.db", isolation_level = None);
c = db.cursor()
#...
c.execute("SELECT UserID FROM ReqMCUDevs WHEN UserID = ?", (UserID,))
if c.fetchall() == []:
c.execute("SELECT MCUID FROM MCUs")
else:
c.execute("""SELECT MCUID FROM MCUDevs
JOIN ReqMCUDevs ON MCUDevs.DevID = ReqMCUDevs.DevID
AND ReqMCUDevs.Quantity <= MCUDevs.Quantity
WHERE ReqMCUDevs.UserID = ?""", (UserID,))
but it is really not the answer
CASE works only in expressions (i.e., to compute a value); it is not possible to change the basic structure of a query conditionally.
However, there are different mechanisms to get what you want.
First, the query with the joins does not actually return anything from the joined tables, so it is possible to rewrite it with a subquery:
SELECT Name,
Price
FROM MCUs
WHERE MCUID IN (SELECT MCUID
FROM MCUDevs
JOIN ReqMCUDevs ON MCUDevs.DevID = ReqMCUDevs.DevID
AND ReqMCUDevs.Quantity >= MCUDevs.Quantity
WHERE ReqMCUDevs.UserID = 7)
ORDER BY Price
Now, we want to ignore this WHERE filter if the subquery is empty.
This can be done with a separate check:
SELECT Name,
Price
FROM MCUs
WHERE MCUID IN (SELECT MCUID
FROM MCUDevs
JOIN ReqMCUDevs ON MCUDevs.DevID = ReqMCUDevs.DevID
AND ReqMCUDevs.Quantity >= MCUDevs.Quantity
WHERE ReqMCUDevs.UserID = 7)
OR NOT EXISTS (SELECT MCUID
FROM MCUDevs
JOIN ReqMCUDevs ON MCUDevs.DevID = ReqMCUDevs.DevID
AND ReqMCUDevs.Quantity >= MCUDevs.Quantity
WHERE ReqMCUDevs.UserID = 7)
ORDER BY Price

GROUP BY / Aggreggate function clarification

I have an SQL Query for each of my 2 Gridview elements. One is getting all the transactions by branch and transaction date:
SELECT
tb_TransactionDetails.TxnID,
tb_TransactionDetails.BranchCode,
tb_TransactionDetails.TxnDate,
tb_TransactionDetails.ReferenceNo,
tb_TransactionType.TxnTypeName,
tb_CurrencyCode.CCYDesc,
tb_TransactionDetails.CCYAmount,
tb_RecordStatus.StatusDesc,
(tb_TransactionName.FirstName + ' ' + ISNULL(tb_TransactionName.MiddleName,'') + ' ' + ISNULL(tb_TransactionName.LastName,'')) as 'Client',
(tb_TransactionName.AddressLine1 + ' ' + ISNULL(tb_TransactionName.AddressLine2, '') + ' ' + ISNULL(tb_TransactionName.AddressLine3, '')) as 'Address',
tb_TransactionName.WhoAdded,
tb_TransactionName.DateAdded,
ROW_NUMBER() OVER
(ORDER BY BranchCode ) AS RowNumber
FROM (((tb_TransactionType inner join tb_TransactionDetails
on tb_TransactionType.TxnTypeCode = tb_TransactionDetails.TxnType)
INNER JOIN tb_CurrencyCode on tb_TransactionDetails.CCYCode = tb_CurrencyCode.CCYCode)
inner join tb_RecordStatus on tb_TransactionDetails.RecordStatus = tb_RecordStatus.StatusCode)
LEFT JOIN tb_TransactionName
on tb_TransactionDetails.TxnID = tb_TransactionName.TxnID
WHERE BranchCode = '1003'
and TxnDate = '12/13/2013'
and one is getting all the users in the system:
select
USR.UserName,
USR.BranchID,
(ISNULL(USR.FirstName,'') + ' ' + ISNULL((SUBSTRING(USR.MiddleName,1,1) + '.' ),'') + ' ' + ISNULL(USR.LastName,'')) as 'Name',
MBS.IsLockedOut,
USR.LastActivityDate,
MAX(STUFF(fxMerge.RoleId, 1, 2, '')) as 'Roles'
from (aspnet_Membership as MBS inner join aspnet_Users as USR
on USR.ApplicationId = USR.ApplicationId and MBS.UserId = USR.UserId)
inner join aspnet_UsersInRoles UIR
on USR.UserId = UIR.UserId
CROSS APPLY(
SELECT ', ' + RoleName
FROM aspnet_UsersInRoles UIR1
INNER JOIN aspnet_Roles RM ON UIR1.RoleId = RM.RoleID
WHERE UIR.UserId = UIR1.UserId
FOR XML PATH('')) fxMerge (RoleId)
where USR.UserName = 'JSmith'
group by USR.UserName, USR.BranchID, USR.FirstName, USR.MiddleName, USR.LastName, MBS.IsLockedOut, USR.LastActivityDate
one thing I'm confused about, is that the 1st query does not need a GROUP BY clause, while the 2nd one does. My question is, why? I've been running the 1st query hundreds of times no problem in my system, without ever having the need of a GROUP BY clause, and the Gridview displays the expected results. While on my 2nd query, It's only when I add the long GROUP BY clause that the query executes successfully on the SQL Server Management studio, then nothing shows up on my Gridview.
That's because your second query has a MAX(). If you want the highest or lowest value, or the count or any other aggregate function, you'll need to specify how to group it.

getting total number to specific patients in rdlc report

I have made an rdlc report of total number of patients in a day and it works fine. I have the total number of female male patients, but when the report binds it returns a total equal to the number of rows in my data.
For example if I have 20 rows in my report then below when I print the count it returns the count in 20 rows.
How can I get it to be in only 1 row?
This is the query I'm using:
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON GO
ALTER PROCEDURE [dbo].[Test_test_test]-- '2013/08/02'
-- Add the parameters for the stored procedure here
-- Add the parameters for the stored procedure here
(#date VARCHAR(20))
AS
BEGIN
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT ( CASE
WHEN OLD_NEW_PATIENT.OLD_NEW = 'new' THEN
PATIENT_REF_MASTER.PAT_ID
ELSE NULL
END ) AS 'new',
( CASE
WHEN OLD_NEW_PATIENT.OLD_NEW = 'old' THEN
PATIENT_REF_MASTER.PAT_ID
ELSE NULL
END ) AS 'old',
----------------------------------------
( CASE
WHEN GENDER_MASTER.NAME1 = 'Female' THEN GENDER_MASTER.NAME1
ELSE NULL
END ) AS
'Females',
( CASE
WHEN GENDER_MASTER.NAME1 = 'Male' THEN GENDER_MASTER.NAME1
ELSE NULL
END ) AS 'Males',
-------------------------------------
CONVERT(VARCHAR, PATIENT_REF_MASTER.CREATION_DATE, 105) AS
'creation_Date',
PATIENT_REF_MASTER.SR_NO AS 'sr_No',
PATIENT_MASTER.PAT_FNAME + ' '
+ PATIENT_MASTER.PAT_SNAME AS 'NAME',
DEPT_ID AS
'Dept_ID',
DEPT_MASTER.DEPT_NAME AS
'Dept_Name',
DOC_MASTER.DOC_ID AS
'Doc_Master',
DOC_MASTER.DOC_FNAME + ' '
+ DOC_MASTER.DOC_SNAME AS
'Doc_Name'
,
PATIENT_MASTER.PAT_ADDR
AS 'addr',
GENDER_MASTER.NAME1 AS
'Pat_Sex',
PATIENT_MASTER.AGE AS 'age',
(SELECT Count(PATIENT_REF_MASTER.SR_NO)
FROM PATIENT_REF_MASTER
WHERE PATIENT_REF_MASTER.CREATION_DATE = #date) AS 'count',
(SELECT Count(PATIENT_MASTER.PAT_SEX)
FROM PATIENT_MASTER
LEFT JOIN PATIENT_REF_MASTER
ON PATIENT_REF_MASTER.PAT_ID =
PATIENT_MASTER.PAT_CODE
WHERE PATIENT_REF_MASTER.CREATION_DATE = #date
AND PATIENT_MASTER.PAT_SEX = 2) AS
'F_count',
(SELECT Count(PATIENT_MASTER.PAT_SEX)
FROM PATIENT_MASTER
LEFT JOIN PATIENT_REF_MASTER
ON PATIENT_REF_MASTER.PAT_ID =
PATIENT_MASTER.PAT_CODE
WHERE PATIENT_REF_MASTER.CREATION_DATE = #date
AND PATIENT_MASTER.PAT_SEX = 1) AS
'M_count'
FROM PATIENT_REF_MASTER
LEFT JOIN DBO.OLD_NEW_PATIENT
ON DBO.OLD_NEW_PATIENT.CODE = PATIENT_REF_MASTER.OLD_NEW
LEFT JOIN DBO.DEPT_MASTER
ON DEPT_MASTER.DEPT_CODE = PATIENT_REF_MASTER.DEPT_ID
LEFT JOIN PATIENT_MASTER
ON PATIENT_MASTER.PAT_CODE = PATIENT_REF_MASTER.PAT_ID
LEFT JOIN DOC_MASTER
ON DOC_MASTER.DOC_ID = PATIENT_REF_MASTER.DOC_ID
LEFT JOIN GENDER_MASTER
ON GENDER_MASTER.CODE = PATIENT_MASTER.PAT_SEX
WHERE PATIENT_REF_MASTER.CREATION_DATE = #date
--MONTH(Patient_Ref_master.creation_Date)=#month and Dept_ID=#dept
ORDER BY PATIENT_REF_MASTER.SR_NO ASC
-- select Dept_Master.Dept_Name as 'Dept_Name',
-- count(Pat_ID) as 'Pat_ID'
--
-- from Patient_Ref_master
--left join dbo.Dept_Master on Dept_Master.Dept_code = Patient_Ref_master.Dept_ID
--where MONTH(Patient_Ref_master.creation_Date)=#month and Dept_ID=#dept
--group by Dept_Master.Dept_Name
END
I think you're trying to do to many things at once ;-)
The heart of your problem lies here:
SELECT Count(PATIENT_MASTER.PAT_SEX)
FROM PATIENT_MASTER
LEFT JOIN PATIENT_REF_MASTER
ON PATIENT_REF_MASTER.PAT_ID =
PATIENT_MASTER.PAT_CODE
WHERE PATIENT_REF_MASTER.CREATION_DATE = #date
AND PATIENT_MASTER.PAT_SEX = 1
By using this query within your query, it will return the total in each and every row. This is also why you can get away with writing the query and not using the GROUP BY clause.
I suggest you do all the work in this query with the exception of the count, and then use another query outside of this one for the count.
A secondary problem is that in your query you're requesting several details about each row, but you want it to come back in one row. You have to decide what you want ;).
In order to get just the counts in one row, try something like this:
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON GO
ALTER PROCEDURE [dbo].[Test_test_test]-- '2013/08/02'
-- Add the parameters for the stored procedure here
-- Add the parameters for the stored procedure here
(#date VARCHAR(20))
AS
BEGIN
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT Count(*) count,
Sum(CASE
WHEN FEMALES IS NOT NULL THEN 1
ELSE 0
END) F_Count,
Sum(CASE
WHEN MALES IS NOT NULL THEN 1
ELSE 0
END) M_Count
FROM (SELECT ( CASE
WHEN OLD_NEW_PATIENT.OLD_NEW = 'new' THEN
PATIENT_REF_MASTER.PAT_ID
ELSE NULL
END ) AS
'new',
( CASE
WHEN OLD_NEW_PATIENT.OLD_NEW = 'old' THEN
PATIENT_REF_MASTER.PAT_ID
ELSE NULL
END ) AS
'old',
----------------------------------------
( CASE
WHEN GENDER_MASTER.NAME1 = 'Female' THEN
GENDER_MASTER.NAME1
ELSE NULL
END ) AS
'Females',
( CASE
WHEN GENDER_MASTER.NAME1 = 'Male' THEN
GENDER_MASTER.NAME1
ELSE NULL
END ) AS
'Males',
-------------------------------------
CONVERT(VARCHAR, PATIENT_REF_MASTER.CREATION_DATE, 105) AS
'creation_Date',
PATIENT_REF_MASTER.SR_NO AS
'sr_No',
PATIENT_MASTER.PAT_FNAME + ' '
+ PATIENT_MASTER.PAT_SNAME AS
'NAME'
,
DEPT_ID
AS 'Dept_ID',
DEPT_MASTER.DEPT_NAME AS
'Dept_Name',
DOC_MASTER.DOC_ID AS
'Doc_Master',
DOC_MASTER.DOC_FNAME + ' '
+ DOC_MASTER.DOC_SNAME AS
'Doc_Name',
PATIENT_MASTER.PAT_ADDR AS
'addr'
,
GENDER_MASTER.NAME1
AS 'Pat_Sex',
PATIENT_MASTER.AGE AS
'age'
FROM PATIENT_REF_MASTER
LEFT JOIN DBO.OLD_NEW_PATIENT
ON DBO.OLD_NEW_PATIENT.CODE =
PATIENT_REF_MASTER.OLD_NEW
LEFT JOIN DBO.DEPT_MASTER
ON DEPT_MASTER.DEPT_CODE =
PATIENT_REF_MASTER.DEPT_ID
LEFT JOIN PATIENT_MASTER
ON PATIENT_MASTER.PAT_CODE =
PATIENT_REF_MASTER.PAT_ID
LEFT JOIN DOC_MASTER
ON DOC_MASTER.DOC_ID = PATIENT_REF_MASTER.DOC_ID
LEFT JOIN GENDER_MASTER
ON GENDER_MASTER.CODE = PATIENT_MASTER.PAT_SEX
WHERE PATIENT_REF_MASTER.CREATION_DATE = #date
--MONTH(Patient_Ref_master.creation_Date)=#month and Dept_ID=#dept
)T
ORDER BY PATIENT_REF_MASTER.SR_NO ASC
END
I hope this helps, let me know if you need any more info.
Edit
Found a small mistake in the query I posted, the field names should have been FEMALES not FEMALE and MALES not MALE.
I also set up a scaled down example in SQL Fiddle. Take a look and tell me what you think.

Modify the sql query in asp.net?

I am using sql server 2005. In this query i want the log-in user detail should also display but it is not displaying .
So please modify the query so that log-in user detail should also display with the help of session[userId].tostring();
Query written by me is:
SELECT DISTINCT MUDMEMBER.PK_ID, MUDMEMBER.EMPLOYEE_ID, LKB.BANK_NAME, MUHD.SALARY_ACCOUNT_NO, MUHD.PF_NO,
MUHD.PAN_NO, MUHD.GENDER, LKD.DESIGNATION_NAME FROM M_LEADERLED MLL INNER JOIN M_USER_DETAILS MUDMEMBER ON
MLL.LED_ID = MUDMEMBER.PK_ID AND MLL.START_DATE <= Getdate() AND MLL.END_DATE > Getdate() AND MLL.LEADER_ID = '1' LEFT OUTER JOIN
M_USER_HR_DETAILS MUHD ON MUHD.FK_USER_ID = MUDMEMBER.PK_ID AND MUHD.IS_ACTIVE =1 LEFT OUTER JOIN
LK_BANKS LKB ON LKB.PK_ID = MUHD.FK_BANK_ID LEFT OUTER JOIN LK_DESIGNATION LKD ON
LKD.DESIGNATION_VALUE = MUHD.FK_DESIGNATION_VALUE AND LKD.FK_ORGANIZATION_ID = 1 AND LKD.IS_ACTIVE = 1 WHERE MUDMEMBER.ACTIVE = 1
ASP.Net Page you can fetch the loggedin user's detail as follows:
SELECT DISTINCT MUDMEMBER.PK_ID, MUDMEMBER.EMPLOYEE_ID, LKB.BANK_NAME, MUHD.SALARY_ACCOUNT_NO, MUHD.PF_NO,
MUHD.PAN_NO, MUHD.GENDER, LKD.DESIGNATION_NAME FROM M_LEADERLED MLL INNER JOIN M_USER_DETAILS MUDMEMBER ON
MLL.LED_ID = MUDMEMBER.PK_ID AND MLL.START_DATE <= Getdate() AND MLL.END_DATE > Getdate()
AND MLL.LEADER_ID = '1' LEFT OUTER JOIN
M_USER_HR_DETAILS MUHD ON MUHD.FK_USER_ID = MUDMEMBER.PK_ID AND MUHD.IS_ACTIVE =1
LEFT OUTER JOIN
LK_BANKS LKB ON LKB.PK_ID = MUHD.FK_BANK_ID LEFT OUTER JOIN LK_DESIGNATION LKD ON
LKD.DESIGNATION_VALUE = MUHD.FK_DESIGNATION_VALUE AND LKD.FK_ORGANIZATION_ID = 1
AND LKD.IS_ACTIVE = 1
WHERE MUDMEMBER.ACTIVE = 1 AND MUDMEMBER.PK_ID ="+Convert.ToInt32(Session["UserId"])+"

Resources