Выберите лучший из левого внешнего объединения

По существу, какой бы ни делает код более простым. Единственная точка выхода является хорошим идеалом, но я не изогнул бы код, не в форме только для достижения его... И если альтернатива объявляет локальную переменную (вне блокировки), инициализируя его (в блокировке) и затем возвращает ее (вне блокировки), затем я сказал бы, что простое "нечто возврата" в блокировке намного более просто.

Для показа различия в IL, позволяет коду:

static class Program
{
    static void Main() { }

    static readonly object sync = new object();

    static int GetValue() { return 5; }

    static int ReturnInside()
    {
        lock (sync)
        {
            return GetValue();
        }
    }

    static int ReturnOutside()
    {
        int val;
        lock (sync)
        {
            val = GetValue();
        }
        return val;
    }
}

(обратите внимание, что я счастливо обсудил бы это ReturnInside более простой/более чистый бит C#),

И посмотрите на IL (режим выпуска и т.д.):

.method private hidebysig static int32 ReturnInside() cil managed
{
    .maxstack 2
    .locals init (
        [0] int32 CS$1$0000,
        [1] object CS$2$0001)
    L_0000: ldsfld object Program::sync
    L_0005: dup 
    L_0006: stloc.1 
    L_0007: call void [mscorlib]System.Threading.Monitor::Enter(object)
    L_000c: call int32 Program::GetValue()
    L_0011: stloc.0 
    L_0012: leave.s L_001b
    L_0014: ldloc.1 
    L_0015: call void [mscorlib]System.Threading.Monitor::Exit(object)
    L_001a: endfinally 
    L_001b: ldloc.0 
    L_001c: ret 
    .try L_000c to L_0014 finally handler L_0014 to L_001b
} 

method private hidebysig static int32 ReturnOutside() cil managed
{
    .maxstack 2
    .locals init (
        [0] int32 val,
        [1] object CS$2$0000)
    L_0000: ldsfld object Program::sync
    L_0005: dup 
    L_0006: stloc.1 
    L_0007: call void [mscorlib]System.Threading.Monitor::Enter(object)
    L_000c: call int32 Program::GetValue()
    L_0011: stloc.0 
    L_0012: leave.s L_001b
    L_0014: ldloc.1 
    L_0015: call void [mscorlib]System.Threading.Monitor::Exit(object)
    L_001a: endfinally 
    L_001b: ldloc.0 
    L_001c: ret 
    .try L_000c to L_0014 finally handler L_0014 to L_001b
}

Таким образом на уровне IL они - [плюс-минус некоторые имена] идентичный (я изучил что-то;-p). По сути, единственное разумное сравнение является (очень субъективным) законом локального стиля кодирования... Я предпочитаю ReturnInside для простоты, но я не пришел бы в восторг от также.

6
задан Anwar Chandra 16 August 2009 в 08:35
поделиться

3 ответа

использование группы по идентификатору пользователя по отношению к таблице hits_table позволяет получить дату обращения max () для каждого идентификатора пользователя. Я назвал это ПОСЛЕДНИЕ ХИТЫ в приведенном ниже коде.

Выбор в ТАБЛИЦЕ ПОЛЬЗОВАТЕЛЕЙ с левым присоединением к ПОСЛЕДНИМ ХИТАМ позволяет получать записи для каждого пользователя.

присоединяясь обратно к ТАБЛИЦЕ ХИТОВ, вы можете вытащить запись браузера, связанную с этой датой, или пустое значение для пользователей, в которых нет записи.

select
   user_table.userid,
   user_table.username,
   isnull(hitstable.browser, 'unknown') as browser
from
  user_table
left join
(
  select
    userid,
    max(hitsdate) hitsdate
  from
    hits_table
  group by  
    userid
) latest_hits
on
  user_table.userid = latest_hits.userid    
left join
  hits_table
on hits.table.userid = latest_hits.userid
and hits_table.hitsdate = latest_hits.hitsdate
7
ответ дан 10 December 2019 в 00:42
поделиться

Не могли бы вы выбрать подвыборку, не красиво, но должно работать ..

SELECT U.*,

ISNULL((SELECT TOP 1 BROWSER 
   FROM HITS_TABLE 
   WHERE HITS_TABLE.USERID = U.USERID
   ORDER BY HITS_TABLE.HITSDATE DESC),'UnKnown') AS Browser

FROM USER_TABLE U
3
ответ дан 10 December 2019 в 00:42
поделиться
SELECT U.*,'BROWSER' = 
    case 
     when (SELECT TOP 1 BROWSER FROM HITS_TABLE WHERE HITS_TABLE.USERID = U.USERID ORDER BY HITS_TABLE.HITSDATE DESC) is  null then 'Unknown'
else (SELECT TOP 1 BROWSER FROM HITS_TABLE WHERE HITS_TABLE.USERID = U.USERID ORDER BY HITS_TABLE.HITSDATE DESC)
    end
FROM USER_TABLE U
0
ответ дан 10 December 2019 в 00:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: