Join tables with rows to columns conversion - sql-server

I have two tables:
Output need to be like this:
select CODE, NAME,
substring_index(DVAR, ',', 1) as DATA1,
(case when numc >= 2 then substring_index(substring_index(DVAR, ',', 2), ',', -1) end) as DATA2,
(case when numc >= 3 then substring_index(substring_index(DVAR, ',', 3), ',', -1) end) as DATA3,
(case when numc >= 4 then substring_index(substring_index(DVAR, ',', 4), ',', -1) end) as DATA4,
(case when numc >= 5 then substring_index(substring_index(DVAR, ',', 5), ',', -1) end) as DATA5,
(case when numc >= 6 then substring_index(substring_index(DVAR, ',', 6), ',', -1) end) as DATA6,
(case when numc >= 7 then substring_index(substring_index(DVAR, ',', 7), ',', -1) end) as DATA7,
(case when numc >= 8 then substring_index(substring_index(DVAR, ',', 8), ',', -1) end) as DATA8,
(case when numc >= 9 then substring_index(substring_index(DVAR, ',', 9), ',', -1) end) as DATA9,
(case when numc >= 10 then substring_index(substring_index(DVAR, ',', 10), ',', -1) end) as DATA10
FROM (
SELECT T2.CODE, T1.NAME, GROUP_CONCAT(T2.DATA SEPARATOR ',') AS DVAR, count(*) as numc
FROM TABLE2 AS T2
LEFT JOIN TABLE1 AS T1 ON T1.CODE=T2.CODE
GROUP BY T2.CODE
) t
I used this code in MySQL and its working.
But I don't know how to do in SQL Server 2012.

You can use PIVOT for a similar effect, eg
CREATE TABLE tbl1 (
Code CHAR(5) NOT NULL,
[Name] VARCHAR(20) NOT NULL
)
CREATE TABLE tbl2 (
Code CHAR(5) NOT NULL,
[Data] VARCHAR(20) NOT NULL
)
INSERT INTO tbl1 ( Code, [Name] )
VALUES
( 'ST101', 'Item1' ),
( 'ST102', 'Item2' ),
( 'ST103', 'Item3' ),
( 'ST104', 'Item4' ),
( 'ST105', 'Item5' )
INSERT INTO tbl2 ( Code, [Data] )
VALUES
( 'ST101', '12345' ),
( 'ST101', '123456' ),
( 'ST101', '123123' ),
( 'ST101', '12412' ),
( 'ST105', '123123' ),
( 'ST105', '11' ),
( 'ST105', '51231' ),
( 'ST105', '411123' ),
( 'ST103', '112312' ),
( 'ST103', '51231' ),
( 'ST103', '442424' ),
( 'ST103', '4233' ),
( 'ST103', '23123' ),
( 'ST103', '1231' ),
( 'ST104', '12312' ),
( 'ST102', '1231' ),
( 'ST102', '51231' ),
( 'ST102', '66452' ),
( 'ST102', '51115' )
GO
;WITH cte AS (
SELECT
t1.Code,
t1.[Name],
t2.[Data],
'Data' + CAST( ROW_NUMBER() OVER( PARTITION BY t1.Code ORDER BY ( SELECT NULL ) ) AS VARCHAR(20) ) rn
FROM tbl1 t1
INNER JOIN tbl2 t2 ON t1.Code = t2.Code
)
SELECT *
FROM cte
PIVOT ( MAX( Data ) For rn In ( Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10 ) ) pvt
If the number of data items is greater than 10 or unknown you should look at dynamic pivot.

Related

How to append specific Word to each column using Dynamic Query in SQL Server

From a temp table I populate from the sys schema, I want to assemble a Dynamic SQL query that appends the word PriorYear to each column alias.
The pseudocode looks like this:
DECLARE #SQLSTR nvarchar(max);
SET #SQLSTR = 'SELECT'
FOR EACH TABLEITEM IN #temptbllist
FOR EACH COLUMNITEM IN #tempschema WHERE table_name = TABLEITEM
SET #SQLSTR COLUMNITEM ' as PriorYear' + COLUMNITEM
ENDFOR
SET #SQLSTR 'FROM ' + TABLEITEM ';'
ENDFOR
Starting with this DDL:
CREATE TABLE #tempschema
(
schema_name VARCHAR(30) NOT NULL,
table_name VARCHAR(30) NOT NULL,
column_name VARCHAR(30) NOT NULL,
)
INSERT INTO #tempschema
VALUES
( 'TestSchema', 'Employee', 'ID'),
( 'TestSchema', 'Employee', 'FirstName'),
( 'TestSchema', 'Employee', 'LastName'),
( 'TestSchema', 'Employee', 'Rank'),
( 'TestSchema', 'Employee', 'Salary'),
( 'TestSchema', 'Facility', 'ID'),
( 'TestSchema', 'Facility', 'FacilityName'),
( 'TestSchema', 'Facility', 'County'),
( 'TestSchema', 'Facility', 'State'),
( 'TestSchema', 'Facility', 'ZipCode'),
( 'TestSchema', 'Manager', 'EmployeeID'),
( 'TestSchema', 'Manager', 'Department'),
( 'TestSchema', 'Manager', 'YearStarted');
CREATE TABLE #temptbllist
(
tblname VARCHAR(30) NOT NULL
)
INSERT INTO #temptbllist
VALUES
('Facility');
Thanks in advance
You can just use two nested STRING_AGG aggregations.
I strongly suggest you also use QUOTENAME to quote the columns and tables correctly.
DECLARE #SQLSTR nvarchar(max);
SELECT #SQLSTR =
STRING_AGG(
CONCAT(
'SELECT
',
ts.columns,
'
FROM ',
QUOTENAME(ts.schema_name),
'.',
QUOTENAME(ts.table_name),
';'
),
'
' )
FROM #temptbllist tt
CROSS APPLY (
SELECT
ts.schema_name,
ts.table_name,
columns = STRING_AGG(CAST(QUOTENAME(ts.column_name) + N' as ' + QUOTENAME(N'PriorYear' + ts.column_name) AS nvarchar(max)), ', ')
FROM #tempschema ts
WHERE ts.table_name = tt.tblname
GROUP BY
ts.schema_name,
ts.table_name
) ts;
db<>fiddle

How can i get data based on condition from within a group by

Consider the following tables
Log (LOG)
Id, CorrId, FlowId, FlowName, AppId, ReqTimestamp, Source, Target, Step, CustomField
Message (MESSAGE)
Id, Url, Method, Headers, MsgBlob, CreatedDatetime
LinkedLogs (LOG_LOGS)
Id, CorrId, LinkedCorId
Create table and insert statements
CREATE TABLE [dbo].[LOG](
[ID] [uniqueidentifier] NOT NULL,
[CORRELATION_ID] [uniqueidentifier] NULL,
[ERROR_CODE] [nvarchar](15) NULL,
[FLOW_ID] [nvarchar](10) NOT NULL,
[APPLICATION_ID] [nvarchar](35) NOT NULL,
[LOG_LEVEL] [nvarchar](35) NOT NULL,
[LOG_TIMESTAMP] [datetime] NOT NULL,
[EVENT_ID] [uniqueidentifier] NOT NULL,
[FLOW_NAME] [nvarchar](50) NOT NULL,
[PROCESS] [nvarchar](256) NOT NULL,
[REQUEST_TIMESTAMP] [datetime] NOT NULL,
[SOURCE] [nvarchar](256) NOT NULL,
[TARGET] [nvarchar](256) NOT NULL,
[STEP] [nvarchar](50) NOT NULL,
[DESCRIPTION] [nvarchar](max) NULL,
[LOG_SEQUENCE] [int] NOT NULL,
[CREATED_DATETIME] [datetime] NOT NULL,
[CUSTOM_FIELD] [nvarchar](60) NULL)
CREATE TABLE [dbo].[MESSAGE](
[ID] [uniqueidentifier] NOT NULL,
[URL] [nvarchar](256) NULL,
[METHOD] [nvarchar](35) NULL,
[MSGBLOB] [varchar](max) NULL,
[HEADERS] [nvarchar](max) NULL,
[CREATED_DATETIME] [datetime] NOT NULL)
CREATE TABLE [dbo].[LOG_LOGS](
[CorrelationId] [uniqueidentifier] NOT NULL,
[LinkedCorrelationId] [uniqueidentifier] NOT NULL,
[CreatedDatetime] [datetime] NULL)
--Log
INSERT [dbo].[LOG]
([ID], [CORRELATION_ID], [ERROR_CODE], [FLOW_ID], [APPLICATION_ID], [LOG_LEVEL], [LOG_TIMESTAMP], [EVENT_ID], [FLOW_NAME], [PROCESS], [REQUEST_TIMESTAMP], [SOURCE], [TARGET], [STEP], [DESCRIPTION], [LOG_SEQUENCE], [CREATED_DATETIME], [CUSTOM_FIELD])
VALUES
('C56BBFBE-5308-4242-ACD0-383F016C0AD1', '8C519F41-1F06-41E5-9647-25554315E1C7', 'NULL', 'TRIGGER', 'appIdString', 'DEBUG', '2019-04-26 14:08:23.660', 'C0F40CA0-682C-11E9-AB6D-0298370A6804', 'trigger', 'imp-trigger', '2019-04-26 14:08:23.660', 'SomeSource', 'SomeTarget', 'START', 'Some description', '1', '2019-04-26 14:08:24.677', 'NULL');
INSERT [dbo].[LOG]
([ID], [CORRELATION_ID], [ERROR_CODE], [FLOW_ID], [APPLICATION_ID], [LOG_LEVEL], [LOG_TIMESTAMP], [EVENT_ID], [FLOW_NAME], [PROCESS], [REQUEST_TIMESTAMP], [SOURCE], [TARGET], [STEP], [DESCRIPTION], [LOG_SEQUENCE], [CREATED_DATETIME], [CUSTOM_FIELD])
VALUES
('273F4E0A-CA7A-40B5-AF54-F2A53A776541', '8C519F41-1F06-41E5-9647-25554315E1C7', 'NULL', 'TRIGGER', 'appIdString', 'DEBUG', '2019-04-26 14:08:25.693', 'C0F40CA0-682C-11E9-AB6D-0298370A6804', 'trigger-melto', 'imp-trigger', '2019-04-26 14:08:23.660', 'SomeSource', 'SomeTarget', 'OUTBOUND', 'Some description', '4', '2019-04-26 14:08:29.110', 'NULL');
INSERT [dbo].[LOG]
([ID], [CORRELATION_ID], [ERROR_CODE], [FLOW_ID], [APPLICATION_ID], [LOG_LEVEL], [LOG_TIMESTAMP], [EVENT_ID], [FLOW_NAME], [PROCESS], [REQUEST_TIMESTAMP], [SOURCE], [TARGET], [STEP], [DESCRIPTION], [LOG_SEQUENCE], [CREATED_DATETIME], [CUSTOM_FIELD])
VALUES
('7AF12EBE-93AC-443F-82CD-9079C2851C9E', '8C519F41-1F06-41E5-9647-25554315E1C7', 'NULL', 'TRIGGER', 'appIdString', 'DEBUG', '2019-04-26 14:08:25.690', 'C0F40CA0-682C-11E9-AB6D-0298370A6804', 'trigger-melto', 'imp-trigger', '2019-04-26 14:08:23.660', 'SomeSource', 'SomeTarget', 'INBOUND', 'Some description', '3', '2019-04-26 14:08:29.270', 'NULL');
INSERT [dbo].[LOG]
([ID], [CORRELATION_ID], [ERROR_CODE], [FLOW_ID], [APPLICATION_ID], [LOG_LEVEL], [LOG_TIMESTAMP], [EVENT_ID], [FLOW_NAME], [PROCESS], [REQUEST_TIMESTAMP], [SOURCE], [TARGET], [STEP], [DESCRIPTION], [LOG_SEQUENCE], [CREATED_DATETIME], [CUSTOM_FIELD])
VALUES
('E0F5018E-8876-4929-828B-E1DB26CF7F30', '8C519F41-1F06-41E5-9647-25554315E1C7', 'NULL', 'TRIGGER', 'appIdString', 'DEBUG', '2019-04-26 14:08:25.477', 'C0F40CA0-682C-11E9-AB6D-0298370A6804', 'trigger-melto', 'imp-trigger', '2019-04-26 14:08:23.660', 'SomeSource', 'SomeTarget', 'OUTBOUND', 'Some description', '2', '2019-04-26 14:08:29.447', 'NULL');
INSERT [dbo].[LOG]
([ID], [CORRELATION_ID], [ERROR_CODE], [FLOW_ID], [APPLICATION_ID], [LOG_LEVEL], [LOG_TIMESTAMP], [EVENT_ID], [FLOW_NAME], [PROCESS], [REQUEST_TIMESTAMP], [SOURCE], [TARGET], [STEP], [DESCRIPTION], [LOG_SEQUENCE], [CREATED_DATETIME], [CUSTOM_FIELD])
VALUES
('8B7A0A86-14D8-4E72-8047-21A73ECF6157', '8C519F41-1F06-41E5-9647-25554315E1C7', '504', 'TRIGGER', 'appIdString', 'DEBUG', '2019-04-26 14:08:35.833', 'C0F40CA0-682C-11E9-AB6D-0298370A6804', 'trigger-melto', 'imp-trigger', '2019-04-26 14:08:23.660', 'SomeSource', 'SomeTarget', 'ERROR', 'Some description', '5', '2019-04-26 14:08:37.500', 'NULL');
-- Message
INSERT INTO [dbo].[MESSAGE]
([ID] ,[URL] ,[METHOD] ,[MSGBLOB] ,[HEADERS] ,[CREATED_DATETIME])
VALUES
('C56BBFBE-5308-4242-ACD0-383F016C0AD1', 'https://localhost:1234/api/trigger', 'POST', 'U29tZSBtZXNzYWdlIGJsb2IgdG8gZGVjb2Rl', '{"Content-Type":"application/xml"}', '2019-04-26 14:08:25.577');
INSERT INTO [dbo].[MESSAGE]
([ID] ,[URL] ,[METHOD] ,[MSGBLOB] ,[HEADERS] ,[CREATED_DATETIME])
VALUES
('273F4E0A-CA7A-40B5-AF54-F2A53A776541', 'NULL', 'NULL', 'U29tZSBtZXNzYWdlIGJsb2IgdG8gZGVjb2Rl', 'null', '2019-04-26 14:08:29.813');
INSERT INTO [dbo].[MESSAGE]
([ID] ,[URL] ,[METHOD] ,[MSGBLOB] ,[HEADERS] ,[CREATED_DATETIME])
VALUES
('E0F5018E-8876-4929-828B-E1DB26CF7F30', 'NULL', 'NULL', 'U29tZSBtZXNzYWdlIGJsb2IgdG8gZGVjb2Rl', 'null', '2019-04-26 14:08:29.613');
INSERT INTO [dbo].[MESSAGE]
([ID] ,[URL] ,[METHOD] ,[MSGBLOB] ,[HEADERS] ,[CREATED_DATETIME])
VALUES
('8B7A0A86-14D8-4E72-8047-21A73ECF6157', 'NULL', 'NULL', 'U29tZSBtZXNzYWdlIGJsb2IgdG8gZGVjb2Rl', 'null', '2019-04-26 14:08:37.817');
-- Log_Logs
INSERT [dbo].[LOG_LOGS]
([CorrelationId], [LinkedCorrelationId], [CreatedDatetime])
VALUES
('8C519F41-1F06-41E5-9647-25554315E1C7', '972039B5-346B-4BC8-AE9B-2A45D51DA310', '2019-06-19 10:54:33.023');
INSERT [dbo].[LOG_LOGS]
([CorrelationId], [LinkedCorrelationId], [CreatedDatetime])
VALUES
('8C519F41-1F06-41E5-9647-25554315E1C7', '972039B5-346B-4BC8-AE9B-2A45D51DA310', '2019-06-19 10:54:33.023');
INSERT [dbo].[LOG_LOGS]
([CorrelationId], [LinkedCorrelationId], [CreatedDatetime])
VALUES
('8C519F41-1F06-41E5-9647-25554315E1C7', '972039B5-346B-4BC8-AE9B-2A45D51DA310', '2019-06-19 10:54:33.023');
INSERT [dbo].[LOG_LOGS]
([CorrelationId], [LinkedCorrelationId], [CreatedDatetime])
VALUES
('8C519F41-1F06-41E5-9647-25554315E1C7', '972039B5-346B-4BC8-AE9B-2A45D51DA310', '2019-06-19 10:54:33.023');
INSERT [dbo].[LOG_LOGS]
([CorrelationId], [LinkedCorrelationId], [CreatedDatetime])
VALUES
('8C519F41-1F06-41E5-9647-25554315E1C7', '972039B5-346B-4BC8-AE9B-2A45D51DA310', '2019-06-19 10:54:33.023');
What i need as a result (paged by 10,20 or 50 records)
Grouped by the Log.CorrId
Log.ReqTimestamp (should be the same for all Log.CorId)
Log.Source (should be the same for all Log.CorId)
Log.Target (should be the same for all Log.CorId)
Log.FlowName (not the same for all Log.CorId: so where Log.Step =
'OUTBOUND', if not available Log.Step = 'END', if not available any
is ok)
CanResubmit: SUM(case when l.STEP = 'START' and DATALENGTH(m.MSGBLOB) > 0 then 1 else 0 end)
HasError: SUM(case when l.STEP = 'ERROR' then 1 else 0 end)
HasEnd: SUM(case when l.STEP = 'END' then 1 else 0 end)
HasLinkedLog
This is what i have so far.
CREATE PROCEDURE [dbo].[sp_SearchFlowCorrelationIds]
#FlowIdList AS dbo.FlowIdList READONLY,
#CorrelationIdList AS dbo.CorrelationIdList READONLY,
#FlowName nvarchar(50) = null,
#Source nvarchar(256) = null,
#Target nvarchar(256) = null,
#ApplicationId nvarchar(35) = null,
#CustomField nvarchar(60) = null,
#Step nvarchar(50) = null,
#DateFrom datetime = null,
#DateTo datetime = null,
#SortField nvarchar(50) = 'RequestTimestamp',
#SortOrder nvarchar(4) = null,
#Take int = 10,
#Skip int = 0
AS
SET NOCOUNT ON
DECLARE #DateBoundaryFrom int = 1;
DECLARE #DateBoundaryTo int = 13;
SELECT result.CORRELATION_ID as CorrelationId
, result.REQUEST_TIMESTAMP as RequestTimestamp
, result.FLOW_NAME as FlowName
, result.SOURCE as Source
, result.TARGET as Target
, result.CanResubmit
, result.HasError
, result.HasEnd
, result.LinkedCorrelationId as LinkedCorrelationId
FROM
(SELECT lastLogged.CORRELATION_ID
, lastLogged.REQUEST_TIMESTAMP
, lastLogged.SOURCE
, lastLogged.TARGET
, lastLogged.FLOW_NAME
, l2.CanResubmit as CanResubmit
, l2.HasError as HasError
, l2.HasEnd as HasEnd
, ll.LinkedCorrelationId
, ROW_NUMBER() OVER (PARTITION BY lastLogged.CORRELATION_ID ORDER BY lastLogged.LOG_TIMESTAMP DESC) as dest_rank
FROM LOG as lastLogged
INNER JOIN (
select CORRELATION_ID
, SUM(case when l.STEP = 'START' and DATALENGTH(m.MSGBLOB) > 0 then 1 else 0 end) as CanResubmit
, SUM(case when l.STEP = 'ERROR' then 1 else 0 end) as HasError
, SUM(case when l.STEP = 'END' then 1 else 0 end) as HasEnd
from LOG l
left join MESSAGE m on l.ID = m.ID
Where l.CREATED_DATETIME >= ISNULL(DATEADD(DAY, -#DateBoundaryFrom, #DateFrom), l.CREATED_DATETIME)
AND l.CREATED_DATETIME <= ISNULL(DATEADD(DAY, #DateBoundaryTo, #DateTo), l.CREATED_DATETIME)
group by l.CORRELATION_ID
) as l2 on lastLogged.CORRELATION_ID = l2.CORRELATION_ID
LEFT JOIN LOG_LOGS ll on lastLogged.CORRELATION_ID = ll.CorrelationId
WHERE
lastLogged.CREATED_DATETIME >= ISNULL(DATEADD(DAY, -#DateBoundaryFrom, #DateFrom), lastLogged.CREATED_DATETIME)
AND lastLogged.CREATED_DATETIME <= ISNULL(DATEADD(DAY, #DateBoundaryTo, #DateTo), lastLogged.CREATED_DATETIME)
AND lastLogged.REQUEST_TIMESTAMP >= ISNULL(#DateFrom, lastLogged.REQUEST_TIMESTAMP)
AND lastLogged.REQUEST_TIMESTAMP <= ISNULL(#DateTo, lastLogged.REQUEST_TIMESTAMP)
AND (lastLogged.FLOW_ID in (SELECT Flow_Id FROM #FlowIdList) OR NOT EXISTS (select 1 from #FlowIdList))
AND (lastLogged.CORRELATION_ID in (SELECT ID FROM #CorrelationIdList) OR NOT EXISTS (select 1 from #CorrelationIdList))
AND lastLogged.FLOW_NAME = ISNULL(#FlowName, lastLogged.FLOW_NAME)
AND lastLogged.SOURCE = ISNULL(#Source, lastLogged.SOURCE)
AND lastLogged.TARGET = ISNULL(#Target, lastLogged.TARGET)
AND lastLogged.APPLICATION_ID = ISNULL(#ApplicationId, lastLogged.APPLICATION_ID)
AND lastLogged.STEP = ISNULL(#Step, lastLogged.STEP)
AND (lastLogged.CUSTOM_FIELD = #CustomField OR #CustomField IS NULL)
) AS result
WHERE result.dest_rank = 1
ORDER BY
-- ASCENDING
CASE
WHEN #SortOrder <> 'ASC' then cast(null as date)
WHEN #SortField = 'RequestTimestamp' then result.REQUEST_TIMESTAMP
end ASC
, CASE
WHEN #SortOrder <> 'ASC' then cast(null as uniqueidentifier)
WHEN #SortField = 'CorrelationId' then result.CORRELATION_ID
end ASC
, CASE
WHEN #SortOrder <> 'ASC' then ''
WHEN #SortField = 'FlowName' then result.FLOW_NAME
end ASC
, CASE
WHEN #SortOrder <> 'ASC' then ''
WHEN #SortField = 'Source' then result.SOURCE
end ASC
, CASE
WHEN #SortOrder <> 'ASC' then ''
WHEN #SortField = 'Target' then result.TARGET
end ASC
-- DESCENDING
, CASE
WHEN #SortOrder <> 'DESC' then cast(null as date)
WHEN #SortField = 'RequestTimestamp' then result.REQUEST_TIMESTAMP
end DESC
, CASE
WHEN #SortOrder <> 'DESC' then cast(null as uniqueidentifier)
WHEN #SortField = 'CorrelationId' then result.CORRELATION_ID
end DESC
, CASE
WHEN #SortOrder <> 'DESC' then ''
WHEN #SortField = 'FlowName' then result.FLOW_NAME
end DESC
, CASE
WHEN #SortOrder <> 'DESC' then ''
WHEN #SortField = 'Source' then result.SOURCE
end DESC
, CASE
WHEN #SortOrder <> 'DESC' then ''
WHEN #SortField = 'Target' then result.TARGET
end DESC
OFFSET #skip ROWS FETCH NEXT #take ROWS ONLY
Question
Now the question is how do i get that FlowName in there based on the following conditions:
where Log.Step = 'OUTBOUND', if not available Log.Step = 'END', if not available any is ok)
(if there are any performance improvements tips, they are always welcome, because this one takes like 8 or more seconds on 7ml records)

sort with subquery not working in cakephp 2

In Controller I have
$this->paginate = array(
'fields' => array(
'User.id', 'User.username', 'User.fullname', 'User.role', 'User.user_remarks',
'( SELECT IFNULL(SUM(B.profit), 0) FROM businesses B WHERE B.user_id = User.id ) +
( SELECT IFNULL(SUM(IFNULL(J.cost, 0)*IFNULL(J.duration, 0)), 0) FROM jobs J WHERE J.user_id = User.id ) +
( SELECT IFNULL(SUM(FI.income), 0) FROM fixed_incomes FI WHERE FI.user_id = User.id ) +
( SELECT IFNULL(SUM(OI.income), 0) FROM other_incomes OI WHERE OI.user_id = User.id ) AS total_income',
'( SELECT IFNULL(SUM(FE.expense), 0) FROM fixed_expenses FE WHERE FE.user_id = User.id ) +
( SELECT IFNULL(SUM(E.cost), 0) FROM expenses E WHERE E.user_id = USER.id ) AS total_expense',
),
'conditions' => $conditions,
);
$this->set('users', $this->Paginator->paginate('User'));
In View I have
<?php echo $this->Paginator->sort('total_income',__("Income (This month)")); ?>
<?php echo $this->Paginator->sort('total_expense',__("Spending (This month)")); ?>
Sorting link is clickable and page refreshes. But sort is not working. Order By virtual column name not appended to query automatically.
Did you try declaring them as virtual fields?
as per:
http://book.cakephp.org/2.0/en/models/virtual-fields.html#virtual-fields-in-sql-queries
try:
$this->virtualFields['total_expense'] = 0;
$this->virtualFields['total_income'] = 0;
$this->paginate = array(
'fields' => array(
'User.id', 'User.username', 'User.fullname', 'User.role', 'User.user_remarks',
'( SELECT IFNULL(SUM(B.profit), 0) FROM businesses B WHERE B.user_id = User.id ) +
( SELECT IFNULL(SUM(IFNULL(J.cost, 0)*IFNULL(J.duration, 0)), 0) FROM jobs J WHERE J.user_id = User.id ) +
( SELECT IFNULL(SUM(FI.income), 0) FROM fixed_incomes FI WHERE FI.user_id = User.id ) +
( SELECT IFNULL(SUM(OI.income), 0) FROM other_incomes OI WHERE OI.user_id = User.id ) AS User__total_income',
'( SELECT IFNULL(SUM(FE.expense), 0) FROM fixed_expenses FE WHERE FE.user_id = User.id ) +
( SELECT IFNULL(SUM(E.cost), 0) FROM expenses E WHERE E.user_id = USER.id ) AS User__total_expense',
),
'conditions' => $conditions,
);
$this->set('users', $this->Paginator->paginate('User'));

List of countries and nationalities in English, Portuguese and Spanish?

Tried to search google for some source who provides list of countries and nationalities in English, Portuguese and Spanish... no luck. Anyone knows one?
A link to a multi language website with a form with any of those list in the three languages would also be great!!
It is in the unicode CLDR - grab the data link from here - http://cldr.unicode.org/index/downloads
unzip the core.zip
Look at main/en.xml, main/pt.xml, main/es.xml
There is a section in the xml for territories, which has the translated list of countries, and their mapping to the ISO-3166-1 code.
The best solution I've found is in:
http://www.mega-db.com.ar/Table/iso3166/Export/SQL/
You have many languages available (including English, Spanish and Portuguese).
-- Create and load Nationality Table - English
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Nationality]') AND type in (N'U'))
DROP TABLE [dbo].[Nationality]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-------------------------------------------------------------------
-- TABLE: [dbo].[Nationality]
-- Creation Date: 02/12/2014
-- Created by: Dan Flynn, Sr. DBA
--
-------------------------------------------------------------------
CREATE TABLE [dbo].[Nationality]
(
[NationalityID] [int] IDENTITY(1,1) NOT NULL,
[Country] [nvarchar](50) NULL,
[Abbreviation] [nvarchar](5) NULL,
[Adjective] [nvarchar] (130) NULL,
[Person] [nvarchar] (60) NULL
) ON [PRIMARY]
GO
-------------------------------------------------------------------------------
-- INSERT VALUES
-------------------------------------------------------------------------------
INSERT INTO [dbo].[Nationality](Country, Abbreviation, Adjective, Person )
VALUES ( 'AMERICAN - USA','US','US (used attributively only, as in US aggression but not He is US)','a US citizen' ),
( 'ARGENTINA','AR','Argentinian','an Argentinian' ),
( 'AUSTRALIA','AU','Australian','an Australian' ),
( 'BAHAMAS','BS','Bahamian','a Bahamian' ),
( 'BELGIUM','BE','Belgian','a Belgian' ),
( 'BRAZIL','BR','Brazilian','a Brazilian' ),
( 'CANADA','CA','Canadian','a Canadian' ),
( 'CHINA','CN','Chinese','a Chinese' ),
( 'COLOMBIA','CO','Colombian','a Colombian' ),
( 'CUBA','CU','Cuban','a Cuban' ),
( 'DOMINICAN REPUBLIC','DO','Dominican','a Dominican' ),
( 'ECUADOR','EC','Ecuadorean','an Ecuadorean' ),
( 'EL SALVADOR','SV','Salvadorean','a Salvadorean' ),
( 'FRANCE','FR','French','a Frenchman, a Frenchwoman' ),
( 'GERMANY','DE','German','a German' ),
( 'GUATEMALA','GT','Guatemalan','a Guatemalan' ),
( 'HAITI','HT','Haitian','a Haitian' ),
( 'HONDURAS','HN','Honduran','a Honduran' ),
( 'INDIA','IN','Indian','an Indian' ),
( 'IRELAND','IE','Ireland','an Irishman, an Irishwoman' ),
( 'ISRAEL','IL','Israeli','an Israeli' ),
( 'ITALY','IT','Italian','an Italian' ),
( 'JAPAN','JP','Japanese','a Japanese' ),
( 'KOREA - REPUBLIC OF','KR','South Korean','a South Korean' ),
( 'MEXICO','MX','Mexican','a Mexican' ),
( 'NETHERLANDS','NL','Dutch','a Dutchman, a Dutchwoman, or a Netherlander' ),
( 'PHILIPPINES','PH','Philippine','a Filipino' ),
( 'SPAIN','ES','Spanish','a Spaniard' ),
( 'SWEDEN','SE','Swedish','a Swede' ),
( 'SWITZERLAND','CH','Swiss','a Swiss' ),
( 'TAIWAN - PROVINCE OF CHINA','TW','Taiwanese','a Taiwanese' ),
( 'UNITED KINGDOM','GB','UK (used attributively only, as in UK time but not He is UK) or British','a Briton' ),
( 'VENEZUELA - BOLIVARIAN REPUBLIC OF','VE','Venezuelan','a Venezuelan' ),
( 'VIET NAM','VN','Vietnamese','a Vietnamese' ),
( 'AFGHANISTAN','AF','Afghan','an Afghan' ),
( 'ÅLAND ISLANDS','AX', NULL, NULL ),
( 'ALBANIA','AL','Albanian','an Albanian' ),
( 'ALGERIA','DZ','Algerian','an Algerian' ),
( 'AMERICAN SAMOA','AS','Samoan','a Samoan' ),
( 'ANDORRA','AD','Andorran','an Andorran' ),
( 'ANGOLA','AO','Angolan','an Angolan' ),
( 'ANGUILLA','AI', NULL, NULL ),
( 'ANTARCTICA','AQ', NULL, NULL ),
( 'ANTIGUA AND BARBUDA','AG', NULL, NULL ),
( 'ARMENIA','AM','Armenian','an Armenian' ),
( 'ARUBA','AW', NULL, NULL ),
( 'AUSTRIA','AT','Austrian','an Austrian' ),
( 'AZERBAIJAN','AZ','Azerbaijani','an Azerbaijani' ),
( 'BAHRAIN','BH','Bahraini','a Bahraini' ),
( 'BANGLADESH','BD','Bangladeshi','a Bangladeshi' ),
( 'BARBADOS','BB','Barbadian','a Barbadian' ),
( 'BELARUS','BY','Belarusian or Belarusan','a Belarusian or a Belarusan' ),
( 'BELIZE','BZ','Belizean','a Belizean' ),
( 'BENIN','BJ','Beninese','a Beninese' ),
( 'BERMUDA','BM','Bermudian','a Bermudian' ),
( 'BHUTAN','BT','Bhutanese','a Bhutanese' ),
( 'BOLIVIA - PLURINATIONAL STATE OF','BO','Bolivian','a Bolivian' ),
( 'BONAIRE - SINT EUSTATIUS AND SABA','BQ', NULL, NULL ),
( 'BOSNIA AND HERZEGOVINA','BA','Bosnian','a Bosnian' ),
( 'BOTSWANA','BW','Botswanan','a Tswana' ),
( 'BOUVET ISLAND','BV', NULL, NULL ),
( 'BRITISH INDIAN OCEAN TERRITORY','IO', NULL, NULL ),
( 'BRUNEI DARUSSALAM','BN', NULL, NULL ),
( 'BULGARIA','BG','Bulgarian','a Bulgarian' ),
( 'BURKINA FASO','BF','Burkinese','a Burkinese' ),
( 'BURUNDI','BI','Burundian','a Burundian' ),
( 'CAMBODIA','KH','Cambodian','a Cambodian' ),
( 'CAMEROON','CM','Cameroonian','a Cameroonian' ),
( 'CAPE VERDE ISLANDS','CV','Cape Verdean','a Cape Verdean' ),
( 'CAYMAN ISLANDS','KY', NULL, NULL ),
( 'CENTRAL AFRICAN REPUBLIC','CF', NULL, NULL ),
( 'CHAD','TD','Chadian','a Chadian' ),
( 'CHILE','CL','Chilean','a Chilean' ),
( 'CHRISTMAS ISLAND','CX', NULL, NULL ),
( 'COCOS (KEELING) ISLANDS','CC', NULL, NULL ),
( 'COMOROS','KM', NULL, NULL ),
( 'CONGO','CG','Congolese','a Congolese' ),
( 'CONGO - THE DEMOCRATIC REPUBLIC OF THE','CD', NULL, NULL ),
( 'COOK ISLANDS','CK', NULL, NULL ),
( 'COSTA RICA','CR','Costa Rican','a Costa Rican' ),
( 'CÔTE D''IVOIRE','CI', NULL, NULL ),
( 'CROATIA','HR','Croat or Croatian','a Croat or a Croatian' ),
( 'CURAÇAO','CW', NULL, NULL ),
( 'CYPRUS','CY','Cypriot','a Cypriot' ),
( 'CZECH REPUBLIC','CZ','Czech','a Czech' ),
( 'DENMARK','DK','Danish','a Dane' ),
( 'DJIBOUTI','DJ','Djiboutian','a Djiboutian' ),
( 'DOMINICA','DM','Dominican','a Dominican' ),
( 'EGYPT','EG','Egyptian','an Egyptian' ),
( 'EQUATORIAL GUINEA','GQ', NULL, NULL ),
( 'ERITREA','ER','Eritrean','an Eritrean' ),
( 'ESTONIA','EE','Estonian','an Estonian' ),
( 'ETHIOPIA','ET','Ethiopian','an Ethiopian' ),
( 'FALKLAND ISLANDS (MALVINAS)','FK', NULL, NULL ),
( 'FAROE ISLANDS','FO', NULL, NULL ),
( 'FIJI','FJ','Fijian','a Fijian' ),
( 'FINLAND','FI','Finnish','a Finn' ),
( 'FRENCH GUIANA','GF', NULL, NULL ),
( 'FRENCH POLYNESIA','PF','French Polynesian','a French Polynesian' ),
( 'FRENCH SOUTHERN TERRITORIES','TF', NULL, NULL ),
( 'GABON','GA','Gabonese','a Gabonese' ),
( 'GAMBIA','GM','Gambian','a Gambian' ),
( 'GEORGIA','GE','Georgian','a Georgian' ),
( 'GHANA','GH','Ghanaian','a Ghanaian' ),
( 'GIBRALTAR','GI', NULL, NULL ),
( 'GREECE','GR','Greek','a Greek' ),
( 'GREENLAND','GL', NULL, NULL ),
( 'GRENADA','GD','Grenadian','a Grenadian' ),
( 'GUADELOUPE','GP', NULL, NULL ),
( 'GUAM','GU', NULL, NULL ),
( 'GUERNSEY','GG', NULL, NULL ),
( 'GUINEA','GN','Guinean','a Guinean' ),
( 'GUINEA-BISSAU','GW', NULL, NULL ),
( 'GUYANA','GY','Guyanese','a Guyanese' ),
( 'HEARD ISLAND AND MCDONALD ISLANDS','HM', NULL, NULL ),
( 'HOLY SEE (VATICAN CITY STATE)','VA', NULL, NULL ),
( 'HONG KONG','HK', NULL, NULL ),
( 'HUNGARY','HU','Hungarian','a Hungarian' ),
( 'ICELAND','IS','Icelandic','an Icelander' ),
( 'INDONESIA','ID','Indonesian','an Indonesian' ),
( 'IRAN - ISLAMIC REPUBLIC OF','IR','Iranian','an Iranian' ),
( 'IRAQ','IQ','Iraqi','an Iraqi' ),
( 'ISLE OF MAN','IM', NULL, NULL ),
( 'JAMAICA','JM','Jamaican','a Jamaican' ),
( 'JERSEY','JE', NULL, NULL ),
( 'JORDAN','JO','Jordanian','a Jordanian' ),
( 'KAZAKHSTAN','KZ','Kazakh','a Kazakh' ),
( 'KENYA','KE','Kenyan','a Kenyan' ),
( 'KIRIBATI','KI', NULL, NULL ),
( 'KOREA - DEMOCRATIC PEOPLE''S REPUBLIC OF','KP','North Korean','a North Korean' ),
( 'KUWAIT','KW','Kuwaiti','a Kuwaiti' ),
( 'KYRGYZSTAN','KG', NULL, NULL ),
( 'LAO PEOPLE''S DEMOCRATIC REPUBLIC','LA', NULL, NULL ),
( 'LATVIA','LV','Latvian','a Latvian' ),
( 'LEBANON','LB','Lebanese','a Lebanese' ),
( 'LESOTHO','LS', NULL, NULL ),
( 'LIBERIA','LR','Liberian','a Liberian' ),
( 'LIBYA','LY','Libyan','a Libyan' ),
( 'LIECHTENSTEIN','LI','-','a Liechtensteiner' ),
( 'LITHUANIA','LT','Lithuanian','a Lithuanian' ),
( 'LUXEMBOURG','LU','-','a Luxembourger' ),
( 'MACAO','MO', NULL, NULL ),
( 'MACEDONIA - THE FORMER YUGOSLAV REPUBLIC OF','MK', NULL, NULL ),
( 'MADAGASCAR','MG','Malagasy or Madagascan','a Malagasy or a Madagascan' ),
( 'MALAWI','MW','Malawian','a Malawian' ),
( 'MALAYSIA','MY','Malaysian','a Malaysian' ),
( 'MALDIVES','MV','Maldivian','a Maldivian' ),
( 'MALI','ML','Malian','a Malian' ),
( 'MALTA','MT','Maltese','a Maltese' ),
( 'MARSHALL ISLANDS','MH', NULL, NULL ),
( 'MARTINIQUE','MQ', NULL, NULL ),
( 'MAURITANIA','MR','Mauritanian','a Mauritanian' ),
( 'MAURITIUS','MU','Mauritian','a Mauritian' ),
( 'MAYOTTE','YT', NULL, NULL ),
( 'MICRONESIA - FEDERATED STATES OF','FM', NULL, NULL ),
( 'MOLDOVA - REPUBLIC OF','MD', NULL, NULL ),
( 'MONACO','MC','Monégasque or Monacan','a Monégasque or a Monacan' ),
( 'MONGOLIA','MN','Mongolian','a Mongolian' ),
( 'MONTENEGRO','ME','Montenegrin','a Montenegrin' ),
( 'MONTSERRAT','MS', NULL, NULL ),
( 'MOROCCO','MA','Moroccan','a Moroccan' ),
( 'MOZAMBIQUE','MZ','Mozambican','a Mozambican' ),
( 'MYANMAR','MM', NULL, NULL ),
( 'NAMIBIA','NA','Namibian','a Namibian' ),
( 'NAURU','NR', NULL, NULL ),
( 'NEPAL','NP','Nepalese','a Nepalese' ),
( 'NEW CALEDONIA','NC', NULL, NULL ),
( 'NEW ZEALAND','NZ','New Zealand (used attributively only, as in New Zealand butter but not He is New Zealand)','a New Zealander' ),
( 'NICARAGUA','NI','Nicaraguan','a Nicaraguan' ),
( 'NIGER','NE','Nigerien','a Nigerien' ),
( 'NIGERIA','NG','Nigerian','a Nigerian' ),
( 'NIUE','NU', NULL, NULL ),
( 'NORFOLK ISLAND','NF', NULL, NULL ),
( 'NORTHERN MARIANA ISLANDS','MP', NULL, NULL ),
( 'NORWAY','NO','Norwegian','a Norwegian' ),
( 'OMAN','OM','Omani','an Omani' ),
( 'PAKISTAN','PK','Pakistani','a Pakistani' ),
( 'PALAU','PW', NULL, NULL ),
( 'PALESTINE - STATE OF','PS', NULL, NULL ),
( 'PANAMA','PA','Panamanian','a Panamanian' ),
( 'PAPUA NEW GUINEA','PG','Papua New Guinean or Guinean','a Papua New Guinean or a Guinean' ),
( 'PARAGUAY','PY','Paraguayan','a Paraguayan' ),
( 'PERU','PE','Peruvian','a Peruvian' ),
( 'PITCAIRN','PN', NULL, NULL ),
( 'POLAND','PL','Polish','a Pole' ),
( 'PORTUGAL','PT','Portuguese','a Portuguese' ),
( 'PUERTO RICO','PR', NULL, NULL ),
( 'QATAR','QA','Qatari','a Qatari' ),
( 'RÉUNION','RE', NULL, NULL ),
( 'ROMANIA','RO','Romanian','a Romanian' ),
( 'RUSSIAN FEDERATION','RU', NULL, NULL ),
( 'RWANDA','RW','Rwandan','a Rwandan' ),
( 'SAINT BARTHÉLEMY','BL', NULL, NULL ),
( 'SAINT HELENA - ASCENSION AND TRISTAN DA CUNHA','SH', NULL, NULL ),
( 'SAINT KITTS AND NEVIS','KN', NULL, NULL ),
( 'SAINT LUCIA','LC', NULL, NULL ),
( 'SAINT MARTIN (FRENCH PART)','MF', NULL, NULL ),
( 'SAINT PIERRE AND MIQUELON','PM', NULL, NULL ),
( 'SAINT VINCENT AND THE GRENADINES','VC', NULL, NULL ),
( 'SAMOA','WS', NULL, NULL ),
( 'SAN MARINO','SM', NULL, NULL ),
( 'SAO TOME AND PRINCIPE','ST', NULL, NULL ),
( 'SAUDI ARABIA','SA','Saudi Arabian or Saudi','a Saudi Arabian or a Saudi' ),
( 'SENEGAL','SN','Senegalese','a Senegalese' ),
( 'SERBIA','RS','Serb or Serbian','a Serb or a Serbian' ),
( 'SEYCHELLES','SC', NULL, NULL ),
( 'SIERRA LEONE','SL','Sierra Leonian','a Sierra Leonian' ),
( 'SINGAPORE','SG','Singaporean','a Singaporean' ),
( 'SINT MAARTEN (DUTCH PART)','SX', NULL, NULL ),
( 'SLOVAKIA','SK','Slovak','a Slovak' ),
( 'SLOVENIA','SI','Slovene or Slovenian','a Slovene or a Slovenian' ),
( 'SOLOMON ISLANDS','SB','-','a Solomon Islander' ),
( 'SOMALIA','SO','Somali','a Somali' ),
( 'SOUTH AFRICA','ZA','South African','a South African' ),
( 'SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS','GS', NULL, NULL ),
( 'SOUTH SUDAN','SS', NULL, NULL ),
( 'SRI LANKA','LK','Sri Lankan','a Sri Lankan' ),
( 'SUDAN','SD','Sudanese','a Sudanese' ),
( 'SURINAME','SR','Surinamese','a Surinamer or a Surinamese' ),
( 'SVALBARD AND JAN MAYEN','SJ', NULL, NULL ),
( 'SWAZILAND','SZ','Swazi','a Swazi' ),
( 'SYRIAN ARAB REPUBLIC','SY', NULL, NULL ),
( 'TAJIKISTAN','TJ','Tajik or Tadjik','a Tajik or a Tadjik' ),
( 'TANZANIA - UNITED REPUBLIC OF','TZ', NULL, NULL ),
( 'THAILAND','TH','Thai','a Thai' ),
( 'TIMOR-LESTE','TL', NULL, NULL ),
( 'TOGO','TG','Togolese','a Togolese' ),
( 'TOKELAU','TK', NULL, NULL ),
( 'TONGA','TO', NULL, NULL ),
( 'TRINIDAD AND TOBAGO','TT','Trinidadian','a Trinidadian' ),
( 'TUNISIA','TN','Tunisian','a Tunisian' ),
( 'TURKEY','TR','Turkish','a Turk' ),
( 'TURKMENISTAN','TM','Turkmen or Turkoman','a Turkmen or a Turkoman' ),
( 'TURKS AND CAICOS ISLANDS','TC', NULL, NULL ),
( 'TUVALU','TV','Tuvaluan','a Tuvaluan' ),
( 'UGANDA','UG','Ugandan','a Ugandan' ),
( 'UKRAINE','UA','Ukrainian','a Ukrainian' ),
( 'UNITED ARAB EMIRATES','AE', NULL, NULL ),
( 'UNITED STATES MINOR OUTLYING ISLANDS','UM', NULL, NULL ),
( 'URUGUAY','UY','Uruguayan','a Uruguayan' ),
( 'UZBEKISTAN','UZ','Uzbek','an Uzbek' ),
( 'VANUATU','VU','Vanuatuan','a Vanuatuan' ),
( 'VIRGIN ISLANDS - BRITISH','VG', NULL, NULL ),
( 'VIRGIN ISLANDS - U.S.','VI', NULL, NULL ),
( 'WALLIS AND FUTUNA','WF', NULL, NULL ),
( 'WESTERN SAHARA','EH', NULL, NULL ),
( 'YEMEN','YE','Yemeni','a Yemeni' ),
( 'ZAMBIA','ZM','Zambian','a Zambian' )
GO
-------------------------------------------------------------------------------
-- ADD CLUSTERED INDEX
-------------------------------------------------------------------------------
CREATE CLUSTERED INDEX [idxNationality] ON [dbo].[Nationality]
(
[NationalityID] ASC,
[Country] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
EXEC sys.sp_addextendedproperty #name=N'TableDiscription', #value=N'CreatedBy: Dan Flynn, Sr. SQL Server DBA
CreationDate: 02/12/2014
Nationality table contains five columns, i.e.:
1. NationalityID, 2. Country, 3. Abbreviation, 4. Adjective, 5. Person
IDs 1 to 34 are alphabetical countries that are statistically the most popular as far as interaction with the United States. IDs 35 to 248 are also alphabetical for the rest of the countries.
' , #level0type=N'SCHEMA',#level0name=N'dbo', #level1type=N'TABLE',#level1name=N'Nationality'
GO

Cakephp beforeFind() - How do I add a JOIN condition AFTER the belongsTo association is added?

I'm in Model->beforeFind($queryData), trying to add a JOIN condition to the queryData on a model which has belongsTo associations. Unfortunately, the new JOIN references a table in the belongsTo association, so it must appear AFTER the belongsTo in the query.
Here is my Tagged->belongsTo association:
app\plugins\tags\models\tagged.php (line 192)
Array
(
[Tag] => Array
(
[className] => Tag
[foreignKey] => tag_id
[conditions] =>
[fields] =>
[order] =>
[counterCache] =>
)
[Group] => Array
(
[className] => Group
[foreignKey] => foreign_key
[conditions] => Array
(
[Tagged.model] => Group
)
[fields] =>
[order] =>
[counterCache] =>
)
)
Here is the JOIN added in Tagged->beforeFind(), notice that the belongsTo joins have not yet been added:
app\plugins\tags\models\tagged.php (line 194)
Array
(
[conditions] => Array
(
[Tag.keyname] => europe
)
[fields] => Array
(
[0] => DISTINCT Group.*
[1] => GroupPermission.*
)
[joins] => Array
(
[0] => Array
(
[table] => permissions
[alias] => GroupPermission
[foreignKey] =>
[type] => INNER
[conditions] => Array
(
[GroupPermission.model] => Group
[0] => GroupPermission.foreignId = Group.id
[or] => Array
( ... )
)
)
)
[limit] =>
[offset] =>
[order] => Array
(
[0] =>
)
[page] => 1
[group] =>
[callbacks] => 1
[by] => europe
[model] => Group
)
When I check the output, it fails with "1054: Unknown column 'Group.id' in 'on clause'" because the Permissions join appeared BEFORE the Groups join.
SELECT DISTINCT `Group`.*, `GroupPermission`.*
FROM `tagged` AS `Tagged`
INNER JOIN permissions AS `GroupPermission` ON (`GroupPermission`.`model` = 'Group' AND `GroupPermission`.`foreignId` = `Group`.`id` AND (...))
LEFT JOIN `tags` AS `Tag` ON (`Tagged`.`tag_id` = `Tag`.`id`)
LEFT JOIN `groups` AS `Group` ON (`Tagged`.`foreign_key` = `Group`.`id` AND `Tagged`.`model` = 'Group')
WHERE `Tag`.`keyname` = 'europe'
But this SQL (with Permissions joined moved to the end) works fine:
SELECT DISTINCT `Group`.*, `GroupPermission`.*
FROM `tagged` AS `Tagged`
LEFT JOIN `tags` AS `Tag` ON (`Tagged`.`tag_id` = `Tag`.`id`)
LEFT JOIN `groups` AS `Group` ON (`Tagged`.`foreign_key` = `Group`.`id` AND `Tagged`.`model` = 'Group')
INNER JOIN permissions AS `GroupPermission` ON (`GroupPermission`.`model` = 'Group' AND `GroupPermission`.`foreignId` = `Group`.`id` AND (...))
WHERE `Tag`.`keyname` = 'europe'
How do I add my join in beforeFind() after the belongsTo join?
The join can not reference anything in the associations, as the associations are fetched via separate queries. If you need to add a join that references an association, you will need to add the association manually in the join as well.

Resources