Один из подходов, который вы можете использовать, - это использовать ассемблер во время сборки для генерации констант во время компиляции.
Первый шаг - создать файл, содержащий все инструкции по сборке, которые вы будете использовать, по одной на строку.
Например:
cmpwi 3,0x20
addi 3,3,0
blr
Назовите этот файл input.def. Затем используйте этот скрипт:
#!/usr/bin/env bash
(cat << HEADER
.global main
.text
main:
HEADER
cat input.def) > asm.s
powerpc-linux-gnu-as asm.s -o asm.o
powerpc-linux-gnu-objdump -d asm.o | \
sed '1,/<main>/ d' | \
paste -d'\t' - input.def | \
awk -F'\t' '{
bytes=$2
asm=$4
disasm=$3
gsub(/ /, "", bytes);
gsub(/[, ]+/, "_", asm);
printf("#define ASM_%-20s 0x%s // disassembly: %s\n", asm, bytes, disasm)
}'
# Clean temporaries
rm asm.s asm.o
(здесь я использую GNU-ассемблер и objdump. Возможно, вам придется изменить эту часть, если вы не используете эти инструменты. Objdump используется в качестве прославленного hexdump утилита здесь.)
Этот скрипт оболочки:
Это большая работа, но вы можете сделать все это во время компиляции.
Это создает заголовочный файл с именем asm.h:
#define ASM_cmpwi_3_0x20 0x2c030020 // disassembly: cmpwi r3,32
#define ASM_addi_3_3_0 0x38630000 // disassembly: addi r3,r3,0
#define ASM_blr 0x4e800020 // disassembly: blr
Вы используете файл asm.h так:
#include "asm.h"
*((volatile int *)(0x80001234)) = ASM_cmpwi_3_0x20;
Если вам нужна новая константа asm, отредактируйте input.def и перезапустите сценарий оболочки.
У Вас есть два варианта здесь. Первое должно иметь два набора результатов, которые установят 'Test1' или 'Test2' на основе условия в WHERE
пункт, и затем UNION
их вместе:
select
'Test1', *
from
TABLE
Where
CCC='D' AND DDD='X' AND exists(select ...)
UNION
select
'Test2', *
from
TABLE
Where
CCC<>'D' AND DDD='X' AND exists(select ...)
Это могло бы быть проблемой, потому что Вы собираетесь эффективно сканировать/искать на ТАБЛИЦЕ дважды.
другое решение состояло бы в том, чтобы выбрать из таблицы однажды и установить 'Test1' или 'Test2' на основе условий в ТАБЛИЦЕ:
select
case
when CCC='D' AND DDD='X' AND exists(select ...) then 'Test1'
when CCC<>'D' AND DDD='X' AND exists(select ...) then 'Test2'
end,
*
from
TABLE
Where
(CCC='D' AND DDD='X' AND exists(select ...)) or
(CCC<>'D' AND DDD='X' AND exists(select ...))
выгода, здесь являющаяся этим, необходимо будет копировать условия фильтра в CASE
оператор и WHERE
оператор.
Если они от той же таблицы, я думаю UNION
, команда, которую Вы ищете.
(Если необходимо было бы когда-либо выбирать значения из столбцов различных таблиц, необходимо посмотреть JOIN
вместо этого...)
Спасибо за вход. Попробованный материал, который был упомянут здесь и это 2, которые я взялся за работу:
(
select 'OK', * from WorkItems t1
where exists(select 1 from workitems t2 where t1.TextField01=t2.TextField01 AND (BoolField05=1) )
AND TimeStamp=(select max(t2.TimeStamp) from workitems t2 where t2.TextField01=t1.TextField01)
AND TimeStamp>'2009-02-12 18:00:00'
AND (BoolField05=1)
)
UNION
(
select 'DEL', * from WorkItems t1
where exists(select 1 from workitems t2 where t1.TextField01=t2.TextField01 AND (BoolField05=1) )
AND TimeStamp=(select max(t2.TimeStamp) from workitems t2 where t2.TextField01=t1.TextField01)
AND TimeStamp>'2009-02-12 18:00:00'
AND NOT (BoolField05=1)
)
И
select
case
when
(BoolField05=1)
then 'OK'
else 'DEL'
end,
*
from WorkItems t1
Where
exists(select 1 from workitems t2 where t1.TextField01=t2.TextField01 AND (BoolField05=1) )
AND TimeStamp=(select max(t2.TimeStamp) from workitems t2 where t2.TextField01=t1.TextField01)
AND TimeStamp>'2009-02-12 18:00:00'
, Который был бы самым эффективным из них (редактирование: второе, поскольку это только сканирует таблицу однажды), и действительно ли возможно сделать это еще более эффективным ? (BoolField=1), действительно переменная (dyn sql), который может содержать любого где оператор на таблице.
я работаю на MS SQL 2005. Попробованные примеры Quassnoi, но не работали как ожидалось.
select Status, * from WorkItems t1
where exists (select 1 from workitems t2 where t1.TextField01=t2.TextField01 AND (BoolField05=1) )
AND TimeStamp=(select max(t2.TimeStamp) from workitems t2 where t2.TextField01=t1.TextField01)
AND TimeStamp>'2009-02-12 18:00:00'
UNION
select 'DELETED', * from WorkItems t1
where exists (select 1 from workitems t2 where t1.TextField01=t2.TextField01 AND (BoolField05=1) )
AND TimeStamp=(select max(t2.TimeStamp) from workitems t2 where t2.TextField01=t1.TextField01)
AND TimeStamp>'2009-02-12 18:00:00'
AND NOT (BoolField05=1)
, Возможно, это добилось бы цели. Я не могу протестировать его отсюда, хотя, и я не уверен, против какой версии SQL Вы работаете.
команда Union - то, в чем Вы нуждаетесь. , Если это не работает, Вы, возможно, должны совершенствовать, в какой среде Вы находитесь.
используйте случай в выбор и используйте в, где близкий a ИЛИ
что-то вроде этого, я не сделал протестировал его, но он должен работать, я думаю...
select case when CCC='D' then 'test1' else 'test2' end, *
from table
where (CCC='D' AND DDD='X') or (CCC<>'D' AND DDD='X')
Я думаю, что это - то, что Вы ищете:
SELECT CASE WHEN BoolField05 = 1 THEN Status ELSE 'DELETED' END AS MyStatus, t1.*
FROM WorkItems t1
WHERE (TextField01, TimeStamp) IN(
SELECT TextField01, MAX(TimeStamp)
FROM WorkItems t2
GROUP BY t2.TextField01
)
AND TimeStamp > '2009-02-12 18:00:00'
, Если Вы находитесь в Oracle или в MS SQL 2005 и выше, затем Вы могли бы сделать:
SELECT *
FROM (
SELECT CASE WHEN BoolField05 = 1 THEN Status ELSE 'DELETED' END AS MyStatus, t1.*,
ROW_NUMBER() OVER (PARTITION BY TextField01 ORDER BY TimeStamp DESC) AS rn
FROM WorkItems t1
) to
WHERE rn = 1
, это более эффективно.